mirror of
				https://github.com/boostorg/unordered.git
				synced 2025-11-03 01:01:42 +01:00 
			
		
		
		
	Merge latest unordered developments:
Make simple_test test a little more. Use doubles for calculating max load factor. Some workarounds, mostly for Borland and running the tests. [SVN r42666]
This commit is contained in:
		@@ -42,8 +42,8 @@ struct assign_base : public test::exception_base
 | 
			
		||||
 | 
			
		||||
    assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
 | 
			
		||||
        : x_values(count1), y_values(count2),
 | 
			
		||||
        x(x_values.begin(), x_values.end(), 0, typename T::hasher(tag1), typename T::key_equal(tag1), typename T::allocator_type(tag1)),
 | 
			
		||||
        y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2), typename T::key_equal(tag2), typename T::allocator_type(tag2)) {}
 | 
			
		||||
        x(x_values.begin(), x_values.end(), 0, BOOST_DEDUCED_TYPENAME T::hasher(tag1), BOOST_DEDUCED_TYPENAME T::key_equal(tag1), BOOST_DEDUCED_TYPENAME T::allocator_type(tag1)),
 | 
			
		||||
        y(y_values.begin(), y_values.end(), 0, BOOST_DEDUCED_TYPENAME T::hasher(tag2), BOOST_DEDUCED_TYPENAME T::key_equal(tag2), BOOST_DEDUCED_TYPENAME T::allocator_type(tag2)) {}
 | 
			
		||||
 | 
			
		||||
    typedef T data_type;
 | 
			
		||||
    T init() const { return T(x); }
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ struct erase_by_key_test1 : public erase_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    void run(T& x) const
 | 
			
		||||
    {
 | 
			
		||||
        typedef 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)
 | 
			
		||||
 
 | 
			
		||||
@@ -43,10 +43,10 @@ struct insert_test_base : public test::exception_base
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test1 : public insert_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    typedef typename insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
 | 
			
		||||
    void run(T& x, strong_type& strong) const {
 | 
			
		||||
        for(typename test::random_values<T>::const_iterator
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
 | 
			
		||||
                it = this->values.begin(), end = this->values.end(); it != end; ++it)
 | 
			
		||||
        {
 | 
			
		||||
            strong.store(x);
 | 
			
		||||
@@ -58,10 +58,10 @@ struct insert_test1 : public insert_test_base<T>
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test2 : public insert_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    typedef typename insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
 | 
			
		||||
    void run(T& x, strong_type& strong) const {
 | 
			
		||||
        for(typename test::random_values<T>::const_iterator
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
 | 
			
		||||
                it = this->values.begin(), end = this->values.end(); it != end; ++it)
 | 
			
		||||
        {
 | 
			
		||||
            strong.store(x);
 | 
			
		||||
@@ -85,10 +85,10 @@ struct insert_test3 : public insert_test_base<T>
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test4 : public insert_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    typedef typename insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
 | 
			
		||||
    void run(T& x, strong_type& strong) const {
 | 
			
		||||
        for(typename test::random_values<T>::const_iterator
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
 | 
			
		||||
                it = this->values.begin(), end = this->values.end(); it != end; ++it)
 | 
			
		||||
        {
 | 
			
		||||
            strong.store(x);
 | 
			
		||||
@@ -100,12 +100,12 @@ struct insert_test4 : public insert_test_base<T>
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test_rehash1 : public insert_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    typedef typename insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
 | 
			
		||||
    insert_test_rehash1() : insert_test_base<T>(1000) {}
 | 
			
		||||
 | 
			
		||||
    T init() const {
 | 
			
		||||
        typedef typename T::size_type size_type;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
 | 
			
		||||
 | 
			
		||||
        T x;
 | 
			
		||||
        x.max_load_factor(0.25);
 | 
			
		||||
@@ -120,11 +120,11 @@ struct insert_test_rehash1 : public insert_test_base<T>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void run(T& x, strong_type& strong) const {
 | 
			
		||||
        typename T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
        int count = 0;
 | 
			
		||||
        typename T::const_iterator pos = x.cbegin();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
 | 
			
		||||
 | 
			
		||||
        for(typename test::random_values<T>::const_iterator
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
 | 
			
		||||
            it = boost::next(this->values.begin(), x.size()), end = this->values.end();
 | 
			
		||||
            it != end && count < 10; ++it, ++count)
 | 
			
		||||
        {
 | 
			
		||||
@@ -141,13 +141,13 @@ struct insert_test_rehash1 : public insert_test_base<T>
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test_rehash2 : public insert_test_rehash1<T>
 | 
			
		||||
{
 | 
			
		||||
    typedef typename insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
 | 
			
		||||
 | 
			
		||||
    void run(T& x, strong_type& strong) const {
 | 
			
		||||
        typename T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
        int count = 0;
 | 
			
		||||
 | 
			
		||||
        for(typename test::random_values<T>::const_iterator
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
 | 
			
		||||
            it = boost::next(this->values.begin(), x.size()), end = this->values.end();
 | 
			
		||||
            it != end && count < 10; ++it, ++count)
 | 
			
		||||
        {
 | 
			
		||||
@@ -164,12 +164,12 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
 | 
			
		||||
template <class T>
 | 
			
		||||
struct insert_test_rehash3 : public insert_test_base<T>
 | 
			
		||||
{
 | 
			
		||||
    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 {
 | 
			
		||||
        typedef typename T::size_type size_type;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
 | 
			
		||||
 | 
			
		||||
        T x;
 | 
			
		||||
        x.max_load_factor(0.25);
 | 
			
		||||
@@ -188,7 +188,7 @@ struct insert_test_rehash3 : public insert_test_base<T>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void run(T& x) const {
 | 
			
		||||
        typename T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
 | 
			
		||||
 | 
			
		||||
        x.insert(boost::next(this->values.begin(), x.size()),
 | 
			
		||||
                boost::next(this->values.begin(), x.size() + 20));
 | 
			
		||||
 
 | 
			
		||||
@@ -54,10 +54,10 @@ 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, typename T::hasher(tag1),
 | 
			
		||||
                typename T::key_equal(tag1), typename T::allocator_type(tag1)),
 | 
			
		||||
        initial_y(y_values.begin(), y_values.end(), 0, typename T::hasher(tag2),
 | 
			
		||||
                typename T::key_equal(tag2), typename T::allocator_type(tag2))
 | 
			
		||||
        initial_x(x_values.begin(), x_values.end(), 0, BOOST_DEDUCED_TYPENAME T::hasher(tag1),
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME T::key_equal(tag1), BOOST_DEDUCED_TYPENAME T::allocator_type(tag1)),
 | 
			
		||||
        initial_y(y_values.begin(), y_values.end(), 0, BOOST_DEDUCED_TYPENAME T::hasher(tag2),
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME T::key_equal(tag2), BOOST_DEDUCED_TYPENAME T::allocator_type(tag2))
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    struct data_type {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,11 +38,15 @@ namespace test
 | 
			
		||||
        const_pointer address(const_reference r) { return &r; }
 | 
			
		||||
 | 
			
		||||
        pointer allocate(size_type n) {
 | 
			
		||||
            using namespace std;
 | 
			
		||||
            return static_cast<T*>(malloc(n * sizeof(T)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pointer allocate(size_type n, const_pointer u) { return allocate(n); }
 | 
			
		||||
        void deallocate(pointer p, size_type) { free(p); }
 | 
			
		||||
        void deallocate(pointer p, size_type) {
 | 
			
		||||
            using namespace std;
 | 
			
		||||
            free(p);
 | 
			
		||||
        }
 | 
			
		||||
        void construct(pointer p, T const& t) { new(p) T(t); }
 | 
			
		||||
        void destroy(pointer p) { p->~T(); }
 | 
			
		||||
 | 
			
		||||
@@ -55,9 +59,11 @@ namespace test
 | 
			
		||||
 | 
			
		||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 | 
			
		||||
        template <class T> void deallocate(T* p, size_type) {
 | 
			
		||||
            using namespace std;
 | 
			
		||||
            free(p);
 | 
			
		||||
        }
 | 
			
		||||
        char* _Charalloc(size_type n) {
 | 
			
		||||
            using namespace std;
 | 
			
		||||
            return static_cast<char*>(malloc(n * sizeof(char)));
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -51,12 +51,12 @@ namespace test
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    class unordered_equivalence_tester
 | 
			
		||||
    {
 | 
			
		||||
        typename Container::size_type size_;
 | 
			
		||||
        typename Container::hasher hasher_;
 | 
			
		||||
        typename Container::key_equal key_equal_;
 | 
			
		||||
        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 typename non_const_value_type<Container>::type value_type;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME non_const_value_type<Container>::type value_type;
 | 
			
		||||
        std::vector<value_type> values_;
 | 
			
		||||
    public:
 | 
			
		||||
        unordered_equivalence_tester(Container const &x)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <boost/type_traits/add_const.hpp>
 | 
			
		||||
 | 
			
		||||
#include "./fwd.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -43,9 +44,10 @@ namespace test
 | 
			
		||||
    struct generator
 | 
			
		||||
    {
 | 
			
		||||
        typedef T value_type;
 | 
			
		||||
        value_type operator()()
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME boost::add_const<T>::type const_value_type;
 | 
			
		||||
        value_type operator()() const
 | 
			
		||||
        {
 | 
			
		||||
            return generate((T const*) 0);
 | 
			
		||||
            return generate((const_value_type*) 0);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ namespace test
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    struct get_key_impl
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename Container::key_type key_type;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME Container::key_type key_type;
 | 
			
		||||
 | 
			
		||||
        static key_type const& get_key(key_type const& x)
 | 
			
		||||
        {
 | 
			
		||||
@@ -32,7 +32,7 @@ namespace test
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template <class Container, class T>
 | 
			
		||||
    inline typename Container::key_type const& get_key(T const& x)
 | 
			
		||||
    inline BOOST_DEDUCED_TYPENAME Container::key_type const& get_key(T const& x)
 | 
			
		||||
    {
 | 
			
		||||
        return get_key_impl<Container>::get_key(x);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,14 @@ namespace test
 | 
			
		||||
    template <class X>
 | 
			
		||||
    void check_equivalent_keys(X const& x1)
 | 
			
		||||
    {
 | 
			
		||||
        typename X::key_equal eq = x1.key_eq();
 | 
			
		||||
        typedef typename X::key_type key_type;
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::key_equal eq = x1.key_eq();
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
 | 
			
		||||
        // Boost.Test was reporting memory leaks for std::set on g++-3.3.
 | 
			
		||||
        // So I work around it by using malloc.
 | 
			
		||||
        std::set<key_type, std::less<key_type>, test::malloc_allocator<key_type> > found_;
 | 
			
		||||
 | 
			
		||||
        typename X::const_iterator it = x1.begin(), end = x1.end();
 | 
			
		||||
        typename X::size_type size = 0;
 | 
			
		||||
        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 occured before, required
 | 
			
		||||
            // to test either that keys are unique or that equivalent keys are
 | 
			
		||||
@@ -70,8 +70,8 @@ namespace test
 | 
			
		||||
 | 
			
		||||
            // // Check that the keys are in the correct bucket and are
 | 
			
		||||
            // // adjacent in the bucket.
 | 
			
		||||
            // typename X::size_type bucket = x1.bucket(key);
 | 
			
		||||
            // typename X::const_local_iterator lit = x1.begin(bucket), lend = x1.end(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");
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,11 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/type_traits/is_same.hpp>
 | 
			
		||||
#include <boost/mpl/eval_if.hpp>
 | 
			
		||||
#include <boost/mpl/if.hpp>
 | 
			
		||||
#include <boost/mpl/identity.hpp>
 | 
			
		||||
#include <boost/mpl/not.hpp>
 | 
			
		||||
#include <boost/mpl/bool.hpp>
 | 
			
		||||
#include <boost/mpl/apply.hpp>
 | 
			
		||||
#include <boost/unordered_set.hpp>
 | 
			
		||||
#include <boost/unordered_map.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -40,8 +41,8 @@ namespace test
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    struct is_set
 | 
			
		||||
        : public boost::is_same<
 | 
			
		||||
            typename Container::key_type,
 | 
			
		||||
            typename Container::value_type> {};
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Container::key_type,
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Container::value_type> {};
 | 
			
		||||
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    struct is_map
 | 
			
		||||
@@ -81,20 +82,29 @@ namespace test
 | 
			
		||||
 | 
			
		||||
    // Non Const Value Type
 | 
			
		||||
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    struct map_non_const_value_type
 | 
			
		||||
    {
 | 
			
		||||
        typedef std::pair<
 | 
			
		||||
            typename Container::key_type,
 | 
			
		||||
            typename Container::mapped_type> type;
 | 
			
		||||
        template <class Container>
 | 
			
		||||
        struct apply {
 | 
			
		||||
            typedef std::pair<
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME Container::key_type,
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME Container::mapped_type> type;
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    struct set_non_const_value_type
 | 
			
		||||
    {
 | 
			
		||||
        template <class Container>
 | 
			
		||||
        struct apply {
 | 
			
		||||
            typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    struct non_const_value_type
 | 
			
		||||
        : boost::mpl::eval_if<is_map<Container>,
 | 
			
		||||
            map_non_const_value_type<Container>,
 | 
			
		||||
            boost::mpl::identity<typename Container::value_type> >
 | 
			
		||||
        : boost::mpl::apply1<
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME boost::mpl::if_<is_map<Container>, map_non_const_value_type, set_non_const_value_type>::type,
 | 
			
		||||
            Container>
 | 
			
		||||
    {
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,10 @@ namespace test
 | 
			
		||||
{
 | 
			
		||||
    template <class X>
 | 
			
		||||
    struct random_values
 | 
			
		||||
        : public std::list<typename X::value_type>
 | 
			
		||||
        : public std::list<BOOST_DEDUCED_TYPENAME X::value_type>
 | 
			
		||||
    {
 | 
			
		||||
        random_values(int count) {
 | 
			
		||||
            typedef typename X::value_type value_type;
 | 
			
		||||
            typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
 | 
			
		||||
            static test::generator<value_type> gen;
 | 
			
		||||
            std::generate_n(std::back_inserter(*this), count, gen);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ namespace test
 | 
			
		||||
    template <class X>
 | 
			
		||||
    class strong
 | 
			
		||||
    {
 | 
			
		||||
        typedef std::vector<typename non_const_value_type<X>::type> values_type;
 | 
			
		||||
        typedef std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type> values_type;
 | 
			
		||||
        values_type values_;
 | 
			
		||||
    public:
 | 
			
		||||
        void store(X const& x) {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ namespace test
 | 
			
		||||
{
 | 
			
		||||
    template <class X>
 | 
			
		||||
    struct equals_to_compare2
 | 
			
		||||
        : public boost::mpl::identity<std::less<typename X::first_argument_type> >
 | 
			
		||||
        : public boost::mpl::identity<std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> >
 | 
			
		||||
    {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@@ -44,8 +44,7 @@ namespace test
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void compare_range(X1 const& x1, X2 const& x2)
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename non_const_value_type<X1>::type value_type;
 | 
			
		||||
        std::vector<value_type> values1, values2;
 | 
			
		||||
        std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X1>::type> values1, values2;
 | 
			
		||||
        values1.reserve(x1.size());
 | 
			
		||||
        values2.reserve(x2.size());
 | 
			
		||||
        std::copy(x1.begin(), x1.end(), std::back_inserter(values1));
 | 
			
		||||
@@ -74,20 +73,20 @@ namespace test
 | 
			
		||||
    struct ordered_set
 | 
			
		||||
        : public boost::mpl::if_<
 | 
			
		||||
            test::has_unique_keys<X>,
 | 
			
		||||
            std::set<typename X::value_type,
 | 
			
		||||
                typename equals_to_compare<typename X::key_equal>::type>,
 | 
			
		||||
            std::multiset<typename X::value_type,
 | 
			
		||||
                typename equals_to_compare<typename X::key_equal>::type>
 | 
			
		||||
            std::set<BOOST_DEDUCED_TYPENAME X::value_type,
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>,
 | 
			
		||||
            std::multiset<BOOST_DEDUCED_TYPENAME X::value_type,
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
 | 
			
		||||
            > {};
 | 
			
		||||
 | 
			
		||||
    template <class X>
 | 
			
		||||
    struct ordered_map
 | 
			
		||||
        : public boost::mpl::if_<
 | 
			
		||||
            test::has_unique_keys<X>,
 | 
			
		||||
            std::map<typename X::key_type, typename X::mapped_type,
 | 
			
		||||
                typename equals_to_compare<typename X::key_equal>::type>,
 | 
			
		||||
            std::multimap<typename X::key_type, typename X::mapped_type,
 | 
			
		||||
                typename equals_to_compare<typename X::key_equal>::type>
 | 
			
		||||
            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>,
 | 
			
		||||
            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>
 | 
			
		||||
            > {};
 | 
			
		||||
 | 
			
		||||
    template <class X>
 | 
			
		||||
@@ -102,9 +101,9 @@ namespace test
 | 
			
		||||
    template <class X>
 | 
			
		||||
    class ordered : public ordered_base<X>::type
 | 
			
		||||
    {
 | 
			
		||||
        typedef typename ordered_base<X>::type base;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base;
 | 
			
		||||
    public:
 | 
			
		||||
        typedef typename base::key_compare key_compare;
 | 
			
		||||
        typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare;
 | 
			
		||||
 | 
			
		||||
        ordered()
 | 
			
		||||
            : base()
 | 
			
		||||
@@ -119,12 +118,12 @@ namespace test
 | 
			
		||||
            compare_range(x, *this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void compare_key(X const& x, typename X::value_type const& val)
 | 
			
		||||
        void compare_key(X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val)
 | 
			
		||||
        {
 | 
			
		||||
            compare_pairs(
 | 
			
		||||
                x.equal_range(get_key<X>(val)),
 | 
			
		||||
                this->equal_range(get_key<X>(val)),
 | 
			
		||||
                (typename non_const_value_type<X>::type*) 0
 | 
			
		||||
                (BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type*) 0
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -138,9 +137,9 @@ namespace test
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template <class Equals>
 | 
			
		||||
    typename equals_to_compare<Equals>::type create_compare(Equals const&)
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare(Equals const&)
 | 
			
		||||
    {
 | 
			
		||||
        typename equals_to_compare<Equals>::type x;
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
 | 
			
		||||
        return x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "../helpers/fwd.hpp"
 | 
			
		||||
#include "../helpers/allocator.hpp"
 | 
			
		||||
#include "memory.hpp"
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
 | 
			
		||||
@@ -53,8 +54,6 @@
 | 
			
		||||
#define DISABLE_EXCEPTIONS \
 | 
			
		||||
    ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
 | 
			
		||||
 | 
			
		||||
#define HASH_CHECK(test) if(!(test)) BOOST_ERROR(BOOST_STRINGIZE(test))
 | 
			
		||||
 | 
			
		||||
namespace test {
 | 
			
		||||
    static char const* scope = "";
 | 
			
		||||
    bool exceptions_enabled = false;
 | 
			
		||||
@@ -151,8 +150,8 @@ namespace test {
 | 
			
		||||
        test_runner(Test const& t) : test_(t) {}
 | 
			
		||||
        void operator()() const {
 | 
			
		||||
            DISABLE_EXCEPTIONS;
 | 
			
		||||
            typename Test::data_type x(test_.init());
 | 
			
		||||
            typename Test::strong_type strong;
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Test::strong_type strong;
 | 
			
		||||
            strong.store(x);
 | 
			
		||||
            try {
 | 
			
		||||
                ENABLE_EXCEPTIONS;
 | 
			
		||||
@@ -179,123 +178,15 @@ namespace exception
 | 
			
		||||
{
 | 
			
		||||
    namespace detail
 | 
			
		||||
    {
 | 
			
		||||
        // This annoymous namespace won't cause ODR violations as I won't
 | 
			
		||||
        // be linking multiple translation units together. I'll probably
 | 
			
		||||
        // move this into a cpp file before a full release, but for now it's
 | 
			
		||||
        // the most convenient way.
 | 
			
		||||
        struct malloc_allocator_holder {
 | 
			
		||||
            template <class T> struct apply {
 | 
			
		||||
                typedef test::malloc_allocator<T> type;
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        namespace
 | 
			
		||||
        {
 | 
			
		||||
            struct memory_area {
 | 
			
		||||
                void const* start;
 | 
			
		||||
                void const* 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) :
 | 
			
		||||
                    tag_(tag) {}
 | 
			
		||||
 | 
			
		||||
                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.
 | 
			
		||||
 | 
			
		||||
            struct memory_area_compare {
 | 
			
		||||
                bool operator()(memory_area const& x, memory_area const& y) const {
 | 
			
		||||
                    return x.end <= y.start;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            typedef std::map<memory_area, memory_track, memory_area_compare,
 | 
			
		||||
                test::malloc_allocator<std::pair<memory_area const, memory_track> > >
 | 
			
		||||
                allocated_memory_type;
 | 
			
		||||
            allocated_memory_type allocated_memory;
 | 
			
		||||
            unsigned int count_allocators = 0;
 | 
			
		||||
            unsigned int count_allocations = 0;
 | 
			
		||||
            unsigned int count_constructions = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void allocator_ref()
 | 
			
		||||
        {
 | 
			
		||||
            if(count_allocators == 0) {
 | 
			
		||||
                count_allocations = 0;
 | 
			
		||||
                count_constructions = 0;
 | 
			
		||||
                allocated_memory.clear();
 | 
			
		||||
            }
 | 
			
		||||
            ++count_allocators;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void allocator_unref()
 | 
			
		||||
        {
 | 
			
		||||
            HASH_CHECK(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();
 | 
			
		||||
 | 
			
		||||
                    HASH_CHECK(no_allocations_left);
 | 
			
		||||
                    HASH_CHECK(no_constructions_left);
 | 
			
		||||
                    HASH_CHECK(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[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)
 | 
			
		||||
        {
 | 
			
		||||
            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 {
 | 
			
		||||
                HASH_CHECK(pos->first.start == ptr);
 | 
			
		||||
                HASH_CHECK(pos->first.end == (char*) ptr + n * size);
 | 
			
		||||
                HASH_CHECK(pos->second.tag_ == tag);
 | 
			
		||||
                allocated_memory.erase(pos);
 | 
			
		||||
            }
 | 
			
		||||
            HASH_CHECK(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)
 | 
			
		||||
        {
 | 
			
		||||
            HASH_CHECK(count_constructions > 0);
 | 
			
		||||
            if(count_constructions > 0) --count_constructions;
 | 
			
		||||
            test::detail::memory_tracker<malloc_allocator_holder> tracker;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -519,7 +410,7 @@ namespace exception
 | 
			
		||||
            SCOPE(allocator::allocator()) {
 | 
			
		||||
                EPOINT("Mock allocator default constructor.");
 | 
			
		||||
            }
 | 
			
		||||
            detail::allocator_ref();
 | 
			
		||||
            detail::tracker.allocator_ref();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
 | 
			
		||||
@@ -527,7 +418,7 @@ namespace exception
 | 
			
		||||
            SCOPE(allocator::allocator()) {
 | 
			
		||||
                EPOINT("Mock allocator template copy constructor.");
 | 
			
		||||
            }
 | 
			
		||||
            detail::allocator_ref();
 | 
			
		||||
            detail::tracker.allocator_ref();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        allocator(allocator const& x) : tag_(x.tag_)
 | 
			
		||||
@@ -535,11 +426,11 @@ namespace exception
 | 
			
		||||
            SCOPE(allocator::allocator()) {
 | 
			
		||||
                EPOINT("Mock allocator copy constructor.");
 | 
			
		||||
            }
 | 
			
		||||
            detail::allocator_ref();
 | 
			
		||||
            detail::tracker.allocator_ref();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~allocator() {
 | 
			
		||||
            detail::allocator_unref();
 | 
			
		||||
            detail::tracker.allocator_unref();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        allocator& operator=(allocator const& x) {
 | 
			
		||||
@@ -577,7 +468,7 @@ namespace exception
 | 
			
		||||
                ptr = (T*) malloc(n * sizeof(T));
 | 
			
		||||
                if(!ptr) throw std::bad_alloc();
 | 
			
		||||
            }
 | 
			
		||||
            detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            return pointer(ptr);
 | 
			
		||||
 | 
			
		||||
            //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
 | 
			
		||||
@@ -593,7 +484,7 @@ namespace exception
 | 
			
		||||
                ptr = (T*) malloc(n * sizeof(T));
 | 
			
		||||
                if(!ptr) throw std::bad_alloc();
 | 
			
		||||
            }
 | 
			
		||||
            detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            return pointer(ptr);
 | 
			
		||||
 | 
			
		||||
            //return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
 | 
			
		||||
@@ -603,7 +494,7 @@ namespace exception
 | 
			
		||||
        {
 | 
			
		||||
            //::operator delete((void*) p);
 | 
			
		||||
            if(p) {
 | 
			
		||||
                detail::track_deallocate((void*) p, n, sizeof(T), tag_);
 | 
			
		||||
                detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
 | 
			
		||||
                using namespace std;
 | 
			
		||||
                free(p);
 | 
			
		||||
            }
 | 
			
		||||
@@ -614,11 +505,11 @@ namespace exception
 | 
			
		||||
                EPOINT("Mock allocator construct function.");
 | 
			
		||||
                new(p) T(t);
 | 
			
		||||
            }
 | 
			
		||||
            detail::track_construct((void*) p, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_construct((void*) p, sizeof(T), tag_);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void destroy(pointer p) {
 | 
			
		||||
            detail::track_destroy((void*) p, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
 | 
			
		||||
            p->~T();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										149
									
								
								test/objects/memory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								test/objects/memory.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
 | 
			
		||||
// Copyright 2006-2007 Daniel James.
 | 
			
		||||
// 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)
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
 | 
			
		||||
#define BOOST_UNORDERED_TEST_MEMORY_HEADER
 | 
			
		||||
 | 
			
		||||
#define HASH_CHECK(test) if(!(test)) BOOST_ERROR(BOOST_STRINGIZE(test))
 | 
			
		||||
 | 
			
		||||
namespace test
 | 
			
		||||
{
 | 
			
		||||
    namespace detail
 | 
			
		||||
    {
 | 
			
		||||
        // This annoymous namespace won't cause ODR violations as I won't
 | 
			
		||||
        // be linking multiple translation units together. I'll probably
 | 
			
		||||
        // move this into a cpp file before a full release, but for now it's
 | 
			
		||||
        // the most convenient way.
 | 
			
		||||
 | 
			
		||||
        struct memory_area {
 | 
			
		||||
            void const* start;
 | 
			
		||||
            void const* 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) {}
 | 
			
		||||
 | 
			
		||||
            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.
 | 
			
		||||
 | 
			
		||||
        struct memory_area_compare {
 | 
			
		||||
            bool operator()(memory_area const& x, memory_area const& y) const {
 | 
			
		||||
                return x.end <= y.start;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct default_allocator_holder { template <class T> struct apply {
 | 
			
		||||
            typedef std::allocator<T> type; }; };
 | 
			
		||||
 | 
			
		||||
        template <class AllocatorHolder = default_allocator_holder>
 | 
			
		||||
        struct memory_tracker {
 | 
			
		||||
            typedef std::map<memory_area, memory_track, memory_area_compare,
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME AllocatorHolder::
 | 
			
		||||
                template apply<std::pair<memory_area const, memory_track> >::type
 | 
			
		||||
            > allocated_memory_type;
 | 
			
		||||
 | 
			
		||||
            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()
 | 
			
		||||
            {
 | 
			
		||||
                HASH_CHECK(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();
 | 
			
		||||
 | 
			
		||||
                        HASH_CHECK(no_allocations_left);
 | 
			
		||||
                        HASH_CHECK(no_constructions_left);
 | 
			
		||||
                        HASH_CHECK(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[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)
 | 
			
		||||
            {
 | 
			
		||||
                BOOST_DEDUCED_TYPENAME 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 {
 | 
			
		||||
                    HASH_CHECK(pos->first.start == ptr);
 | 
			
		||||
                    HASH_CHECK(pos->first.end == (char*) ptr + n * size);
 | 
			
		||||
                    HASH_CHECK(pos->second.tag_ == tag);
 | 
			
		||||
                    allocated_memory.erase(pos);
 | 
			
		||||
                }
 | 
			
		||||
                HASH_CHECK(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)
 | 
			
		||||
            {
 | 
			
		||||
                HASH_CHECK(count_constructions > 0);
 | 
			
		||||
                if(count_constructions > 0) --count_constructions;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -9,8 +9,9 @@
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/limits.hpp>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include "../helpers/fwd.hpp"
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "../helpers/fwd.hpp"
 | 
			
		||||
#include "memory.hpp"
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
namespace test
 | 
			
		||||
@@ -203,141 +204,8 @@ namespace test
 | 
			
		||||
 | 
			
		||||
    namespace detail
 | 
			
		||||
    {
 | 
			
		||||
        // This annoymous namespace won't cause ODR violations as I won't
 | 
			
		||||
        // be linking multiple translation units together. I'll probably
 | 
			
		||||
        // move this into a cpp file before a full release, but for now it's
 | 
			
		||||
        // the most convenient way.
 | 
			
		||||
        namespace {
 | 
			
		||||
            struct memory_area {
 | 
			
		||||
                void const* start;
 | 
			
		||||
                void const* 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) {}
 | 
			
		||||
 | 
			
		||||
                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.
 | 
			
		||||
 | 
			
		||||
            struct memory_area_compare {
 | 
			
		||||
                bool operator()(memory_area const& x, memory_area const& y) const {
 | 
			
		||||
                    return x.end <= y.start;
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            typedef std::map<memory_area, memory_track, memory_area_compare> allocated_memory_type;
 | 
			
		||||
            allocated_memory_type allocated_memory;
 | 
			
		||||
            unsigned int count_allocators = 0;
 | 
			
		||||
            unsigned int count_allocations = 0;
 | 
			
		||||
            unsigned int 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[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)
 | 
			
		||||
        {
 | 
			
		||||
            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);
 | 
			
		||||
                BOOST_TEST(pos->second.tag_ == tag);
 | 
			
		||||
                BOOST_TEST(pos->second.constructed_ == 0);
 | 
			
		||||
                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)
 | 
			
		||||
        {
 | 
			
		||||
            allocated_memory_type::iterator pos
 | 
			
		||||
                = allocated_memory.find(memory_area(ptr, (char*) ptr + size));
 | 
			
		||||
            if(pos == allocated_memory.end()) {
 | 
			
		||||
                BOOST_ERROR("Constructing unknown pointer.");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                BOOST_TEST(pos->second.tag_ == tag);
 | 
			
		||||
                ++pos->second.constructed_;
 | 
			
		||||
            }
 | 
			
		||||
            ++count_constructions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void track_destroy(void* ptr, std::size_t size, int tag)
 | 
			
		||||
        {
 | 
			
		||||
            allocated_memory_type::iterator pos
 | 
			
		||||
                = allocated_memory.find(memory_area(ptr, (char*) ptr + size));
 | 
			
		||||
            if(pos == allocated_memory.end())
 | 
			
		||||
                BOOST_ERROR("Destroying unknown pointer.");
 | 
			
		||||
            else {
 | 
			
		||||
                BOOST_TEST(pos->second.tag_ == tag);
 | 
			
		||||
                BOOST_TEST(pos->second.constructed_ > 0);
 | 
			
		||||
                if(pos->second.constructed_ > 0) --pos->second.constructed_;
 | 
			
		||||
            }
 | 
			
		||||
            BOOST_TEST(count_constructions > 0);
 | 
			
		||||
            if(count_constructions > 0) --count_constructions;
 | 
			
		||||
            test::detail::memory_tracker<test::detail::default_allocator_holder> tracker;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -361,40 +229,40 @@ namespace test
 | 
			
		||||
 | 
			
		||||
        template <class U> struct rebind { typedef allocator<U> other; };
 | 
			
		||||
 | 
			
		||||
        explicit allocator(int t = 0) : tag_(t) { detail::allocator_ref(); }
 | 
			
		||||
        template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::allocator_ref(); }
 | 
			
		||||
        allocator(allocator const& x) : tag_(x.tag_) { detail::allocator_ref(); }
 | 
			
		||||
        ~allocator() { detail::allocator_unref(); }
 | 
			
		||||
        explicit allocator(int t = 0) : tag_(t) { detail::tracker.allocator_ref(); }
 | 
			
		||||
        template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
 | 
			
		||||
        allocator(allocator const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
 | 
			
		||||
        ~allocator() { detail::tracker.allocator_unref(); }
 | 
			
		||||
 | 
			
		||||
        pointer address(reference r) { return pointer(&r); }
 | 
			
		||||
        const_pointer address(const_reference r) { return const_pointer(&r); }
 | 
			
		||||
 | 
			
		||||
        pointer allocate(size_type n) {
 | 
			
		||||
            pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
 | 
			
		||||
            detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            return ptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pointer allocate(size_type n, const_pointer u)
 | 
			
		||||
        {
 | 
			
		||||
            pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
 | 
			
		||||
            detail::track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
 | 
			
		||||
            return ptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void deallocate(pointer p, size_type n)
 | 
			
		||||
        {
 | 
			
		||||
            detail::track_deallocate((void*) p, n, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
 | 
			
		||||
            ::operator delete((void*) p);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void construct(pointer p, T const& t) {
 | 
			
		||||
            detail::track_construct((void*) p, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_construct((void*) p, sizeof(T), tag_);
 | 
			
		||||
            new(p) T(t);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void destroy(pointer p) {
 | 
			
		||||
            detail::track_destroy((void*) p, sizeof(T), tag_);
 | 
			
		||||
            detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
 | 
			
		||||
            p->~T();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,8 @@ test::seed_t seed(96785);
 | 
			
		||||
template <class T>
 | 
			
		||||
void assign_tests1(T* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typename T::hasher hf;
 | 
			
		||||
    typename T::key_equal eq;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq;
 | 
			
		||||
 | 
			
		||||
    std::cerr<<"assign_tests1.1\n";
 | 
			
		||||
    {
 | 
			
		||||
@@ -52,12 +52,12 @@ void assign_tests1(T* = 0)
 | 
			
		||||
template <class T>
 | 
			
		||||
void assign_tests2(T* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typename T::hasher hf1(1);
 | 
			
		||||
    typename T::hasher hf2(2);
 | 
			
		||||
    typename T::key_equal eq1(1);
 | 
			
		||||
    typename T::key_equal eq2(2);
 | 
			
		||||
    typename T::allocator_type al1(1);
 | 
			
		||||
    typename T::allocator_type al2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
 | 
			
		||||
 | 
			
		||||
    std::cerr<<"assign_tests2.1\n";
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,8 @@ test::seed_t seed(54635);
 | 
			
		||||
template <class X>
 | 
			
		||||
void bucket_tests(X* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::size_type size_type;
 | 
			
		||||
    typedef typename X::const_local_iterator const_local_iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
 | 
			
		||||
    test::random_values<X> v(1000);
 | 
			
		||||
 | 
			
		||||
    X x(v.begin(), v.end());
 | 
			
		||||
@@ -25,7 +25,7 @@ void bucket_tests(X* = 0)
 | 
			
		||||
    BOOST_TEST(x.bucket_count() < x.max_bucket_count());
 | 
			
		||||
    std::cerr<<x.bucket_count()<<"<"<<x.max_bucket_count()<<"\n";
 | 
			
		||||
 | 
			
		||||
    for(typename test::random_values<X>::const_iterator
 | 
			
		||||
    for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
 | 
			
		||||
            it = v.begin(), end = v.end(); it != end; ++it)
 | 
			
		||||
    {
 | 
			
		||||
        size_type bucket = x.bucket(test::get_key<X>(*it));
 | 
			
		||||
 
 | 
			
		||||
@@ -29,19 +29,19 @@ template <class T> void sink(T const&) {}
 | 
			
		||||
template <class X, class T>
 | 
			
		||||
void container_test(X& r, T&)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef typename X::const_iterator const_iterator;
 | 
			
		||||
    typedef typename X::difference_type difference_type;
 | 
			
		||||
    typedef typename X::size_type size_type;
 | 
			
		||||
    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 typename boost::iterator_value<iterator>::type iterator_value_type;
 | 
			
		||||
    typedef typename boost::iterator_value<const_iterator>::type const_iterator_value_type;
 | 
			
		||||
    typedef typename boost::iterator_difference<iterator>::type iterator_difference_type;
 | 
			
		||||
    typedef 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 typename X::value_type value_type;
 | 
			
		||||
    typedef typename X::reference reference;
 | 
			
		||||
    typedef typename X::const_reference const_reference;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::reference reference;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::const_reference const_reference;
 | 
			
		||||
 | 
			
		||||
    // value_type
 | 
			
		||||
 | 
			
		||||
@@ -132,8 +132,8 @@ void container_test(X& r, T&)
 | 
			
		||||
template <class X, class Key>
 | 
			
		||||
void unordered_set_test(X&, Key const&)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::value_type value_type;
 | 
			
		||||
    typedef typename X::key_type key_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
 | 
			
		||||
 | 
			
		||||
    BOOST_MPL_ASSERT((boost::is_same<value_type, key_type>));
 | 
			
		||||
}
 | 
			
		||||
@@ -141,29 +141,29 @@ void unordered_set_test(X&, Key const&)
 | 
			
		||||
template <class X, class Key, class T>
 | 
			
		||||
void unordered_map_test(X&, Key const&, T const&)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::value_type value_type;
 | 
			
		||||
    typedef typename X::key_type key_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
 | 
			
		||||
    BOOST_MPL_ASSERT((boost::is_same<value_type, std::pair<key_type const, T> >));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class X, class T>
 | 
			
		||||
void unordered_unique_test(X& r, T const& t)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 | 
			
		||||
    test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class X, class T>
 | 
			
		||||
void unordered_equivalent_test(X& r, T const& t)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 | 
			
		||||
    test::check_return_type<iterator>::equals(r.insert(t));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class X, class Key, class T>
 | 
			
		||||
void unordered_map_functions(X&, Key const& k, T const&)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::mapped_type mapped_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type;
 | 
			
		||||
 | 
			
		||||
    X a;
 | 
			
		||||
    test::check_return_type<mapped_type>::equals_ref(a[k]);
 | 
			
		||||
@@ -176,35 +176,35 @@ void unordered_map_functions(X&, Key const& k, T const&)
 | 
			
		||||
template <class X, class Key, class T, class Hash, class Pred>
 | 
			
		||||
void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::key_type key_type;
 | 
			
		||||
    typedef typename X::hasher hasher;
 | 
			
		||||
    typedef typename X::key_equal key_equal;
 | 
			
		||||
    typedef typename X::size_type size_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::hasher hasher;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::key_equal key_equal;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
 | 
			
		||||
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef typename X::const_iterator const_iterator;
 | 
			
		||||
    typedef typename X::local_iterator local_iterator;
 | 
			
		||||
    typedef typename X::const_local_iterator const_local_iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 | 
			
		||||
    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 typename boost::BOOST_ITERATOR_CATEGORY<iterator>::type iterator_category;
 | 
			
		||||
    typedef typename boost::iterator_difference<iterator>::type iterator_difference;
 | 
			
		||||
    typedef typename boost::iterator_pointer<iterator>::type iterator_pointer;
 | 
			
		||||
    typedef typename boost::iterator_reference<iterator>::type iterator_reference;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME 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 iterator_pointer;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<iterator>::type iterator_reference;
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type local_iterator_category;
 | 
			
		||||
    typedef typename boost::iterator_difference<local_iterator>::type local_iterator_difference;
 | 
			
		||||
    typedef typename boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
 | 
			
		||||
    typedef typename boost::iterator_reference<local_iterator>::type local_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 local_iterator_pointer;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<local_iterator>::type local_iterator_reference;
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type const_iterator_category;
 | 
			
		||||
    typedef typename boost::iterator_difference<const_iterator>::type const_iterator_difference;
 | 
			
		||||
    typedef typename boost::iterator_pointer<const_iterator>::type const_iterator_pointer;
 | 
			
		||||
    typedef typename boost::iterator_reference<const_iterator>::type const_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 const_iterator_pointer;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<const_iterator>::type const_iterator_reference;
 | 
			
		||||
 | 
			
		||||
    typedef typename boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type const_local_iterator_category;
 | 
			
		||||
    typedef typename boost::iterator_difference<const_local_iterator>::type const_local_iterator_difference;
 | 
			
		||||
    typedef typename boost::iterator_pointer<const_local_iterator>::type const_local_iterator_pointer;
 | 
			
		||||
    typedef 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;
 | 
			
		||||
 | 
			
		||||
    BOOST_MPL_ASSERT((boost::is_same<Key, key_type>));
 | 
			
		||||
    boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
 | 
			
		||||
@@ -237,8 +237,8 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
 | 
			
		||||
    X();
 | 
			
		||||
    X a4;
 | 
			
		||||
 | 
			
		||||
    typename X::value_type* i = 0;
 | 
			
		||||
    typename X::value_type* j = 0;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME X::value_type* i = 0;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME X::value_type* j = 0;
 | 
			
		||||
 | 
			
		||||
    X(i, j, 10, hf, eq);
 | 
			
		||||
    X a5(i, j, 10, hf, eq);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,9 +20,9 @@ test::seed_t seed(356730);
 | 
			
		||||
template <class T>
 | 
			
		||||
void constructor_tests1(T* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typename T::hasher hf;
 | 
			
		||||
    typename T::key_equal eq;
 | 
			
		||||
    typename T::allocator_type al;
 | 
			
		||||
    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";
 | 
			
		||||
    {
 | 
			
		||||
@@ -139,15 +139,15 @@ void constructor_tests1(T* = 0)
 | 
			
		||||
template <class T>
 | 
			
		||||
void constructor_tests2(T* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typename T::hasher hf;
 | 
			
		||||
    typename T::hasher hf1(1);
 | 
			
		||||
    typename T::hasher hf2(2);
 | 
			
		||||
    typename T::key_equal eq;
 | 
			
		||||
    typename T::key_equal eq1(1);
 | 
			
		||||
    typename T::key_equal eq2(2);
 | 
			
		||||
    typename T::allocator_type al;
 | 
			
		||||
    typename T::allocator_type al1(1);
 | 
			
		||||
    typename T::allocator_type al2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq2(2);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
 | 
			
		||||
 | 
			
		||||
    std::cerr<<"Construct 1\n";
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,9 @@ test::seed_t seed(9063);
 | 
			
		||||
template <class T>
 | 
			
		||||
void copy_construct_tests1(T* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typename T::hasher hf;
 | 
			
		||||
    typename T::key_equal eq;
 | 
			
		||||
    typename T::allocator_type al;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq;
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al;
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        T x;
 | 
			
		||||
@@ -64,9 +64,9 @@ void copy_construct_tests2(T* ptr = 0)
 | 
			
		||||
{
 | 
			
		||||
    copy_construct_tests1(ptr);
 | 
			
		||||
 | 
			
		||||
    typename T::hasher hf(1);
 | 
			
		||||
    typename T::key_equal eq(1);
 | 
			
		||||
    typename T::allocator_type al(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::hasher hf(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
 | 
			
		||||
    BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        T x(10000, hf, eq, al);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ void erase_tests1(Container* = 0)
 | 
			
		||||
    {
 | 
			
		||||
        test::random_values<Container> v(1000);
 | 
			
		||||
        Container x(v.begin(), v.end());
 | 
			
		||||
        for(typename test::random_values<Container>::iterator it = v.begin();
 | 
			
		||||
        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));
 | 
			
		||||
@@ -43,9 +43,9 @@ void erase_tests1(Container* = 0)
 | 
			
		||||
        std::size_t size = x.size();
 | 
			
		||||
        while(size > 0 && !x.empty())
 | 
			
		||||
        {
 | 
			
		||||
            typename Container::key_type key = test::get_key<Container>(*x.begin());
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*x.begin());
 | 
			
		||||
            std::size_t count = x.count(key);
 | 
			
		||||
            typename Container::iterator pos = x.erase(x.begin());
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Container::iterator pos = x.erase(x.begin());
 | 
			
		||||
            --size;
 | 
			
		||||
            BOOST_TEST(pos == x.begin());
 | 
			
		||||
            BOOST_TEST(x.count(key) == count - 1);
 | 
			
		||||
@@ -63,7 +63,7 @@ void erase_tests1(Container* = 0)
 | 
			
		||||
        {
 | 
			
		||||
            using namespace std;
 | 
			
		||||
            int index = rand() % x.size();
 | 
			
		||||
            typename Container::const_iterator prev, pos, next;
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
 | 
			
		||||
            if(index == 0) {
 | 
			
		||||
                prev = pos = x.begin();
 | 
			
		||||
            }
 | 
			
		||||
@@ -72,7 +72,7 @@ void erase_tests1(Container* = 0)
 | 
			
		||||
                pos = boost::next(prev);
 | 
			
		||||
            }
 | 
			
		||||
            next = boost::next(pos);
 | 
			
		||||
            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(next == x.erase(pos));
 | 
			
		||||
            --size;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ test::seed_t seed(78937);
 | 
			
		||||
template <class X>
 | 
			
		||||
void find_tests1(X*)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        test::random_values<X> v(500);
 | 
			
		||||
@@ -25,12 +25,12 @@ void find_tests1(X*)
 | 
			
		||||
        test::ordered<X> tracker = test::create_ordered(x);
 | 
			
		||||
        tracker.insert_range(v.begin(), v.end());
 | 
			
		||||
 | 
			
		||||
        for(typename test::ordered<X>::const_iterator it1 =
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 =
 | 
			
		||||
                tracker.begin(); it1 != tracker.end(); ++it1)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::key_type key = test::get_key<X>(*it1);
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
 | 
			
		||||
            iterator pos = x.find(key);
 | 
			
		||||
            typename X::const_iterator const_pos = x_const.find(key);
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::const_iterator const_pos = x_const.find(key);
 | 
			
		||||
            BOOST_TEST(pos != x.end() &&
 | 
			
		||||
                    x.key_eq()(key, test::get_key<X>(*pos)));
 | 
			
		||||
            BOOST_TEST(const_pos != x_const.end() &&
 | 
			
		||||
@@ -40,17 +40,17 @@ void find_tests1(X*)
 | 
			
		||||
 | 
			
		||||
            test::compare_pairs(x.equal_range(key),
 | 
			
		||||
                    tracker.equal_range(key),
 | 
			
		||||
                    (typename test::non_const_value_type<X>::type*) 0);
 | 
			
		||||
                    (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
 | 
			
		||||
            test::compare_pairs(x_const.equal_range(key),
 | 
			
		||||
                    tracker.equal_range(key),
 | 
			
		||||
                    (typename test::non_const_value_type<X>::type*) 0);
 | 
			
		||||
                    (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v2(500);
 | 
			
		||||
        for(typename test::random_values<X>::const_iterator it2 =
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 =
 | 
			
		||||
                v2.begin(); it2 != v2.end(); ++it2)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::key_type key = test::get_key<X>(*it2);
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2);
 | 
			
		||||
            if(tracker.find(test::get_key<X>(key)) == tracker.end())
 | 
			
		||||
            {
 | 
			
		||||
                BOOST_TEST(x.find(key) == x.end());
 | 
			
		||||
@@ -66,10 +66,10 @@ void find_tests1(X*)
 | 
			
		||||
        X x;
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v2(5);
 | 
			
		||||
        for(typename test::random_values<X>::const_iterator it3 =
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 =
 | 
			
		||||
                v2.begin(); it3 != v2.end(); ++it3)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::key_type key = test::get_key<X>(*it3);
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
 | 
			
		||||
            BOOST_TEST(x.find(key) == x.end());
 | 
			
		||||
            BOOST_TEST(x.count(key) == 0);
 | 
			
		||||
            std::pair<iterator, iterator> range = x.equal_range(key);
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,8 @@ test::seed_t seed(243432);
 | 
			
		||||
template <class X>
 | 
			
		||||
void unique_insert_tests1(X* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
 | 
			
		||||
    typedef test::ordered<X> ordered;
 | 
			
		||||
    typedef typename test::ordered<X>::iterator ordered_iterator;
 | 
			
		||||
 | 
			
		||||
    std::cerr<<"insert(value) tests for containers with unique keys.\n";
 | 
			
		||||
 | 
			
		||||
@@ -31,14 +30,16 @@ void unique_insert_tests1(X* = 0)
 | 
			
		||||
    test::ordered<X> tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
    test::random_values<X> v(1000);
 | 
			
		||||
    for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
 | 
			
		||||
    for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
            it != v.end(); ++it)
 | 
			
		||||
    {
 | 
			
		||||
        typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
        float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
        std::pair<iterator, bool> r1 = x.insert(*it);
 | 
			
		||||
        std::pair<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);
 | 
			
		||||
@@ -61,14 +62,14 @@ void equivalent_insert_tests1(X* = 0)
 | 
			
		||||
    test::ordered<X> tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
    test::random_values<X> v(1000);
 | 
			
		||||
    for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
    for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
            it != v.end(); ++it)
 | 
			
		||||
    {
 | 
			
		||||
        typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
        float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
        typename X::iterator r1 = x.insert(*it);
 | 
			
		||||
        typename test::ordered<X>::iterator r2 = tracker.insert(*it);
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(*r1 == *r2);
 | 
			
		||||
 | 
			
		||||
@@ -84,10 +85,10 @@ void equivalent_insert_tests1(X* = 0)
 | 
			
		||||
template <class X>
 | 
			
		||||
void insert_tests2(X* = 0)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename test::ordered<X> tracker_type;
 | 
			
		||||
    typedef typename X::iterator iterator;
 | 
			
		||||
    typedef typename X::const_iterator const_iterator;
 | 
			
		||||
    typedef typename tracker_type::iterator tracker_iterator;
 | 
			
		||||
    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";
 | 
			
		||||
 | 
			
		||||
@@ -96,10 +97,10 @@ void insert_tests2(X* = 0)
 | 
			
		||||
        tracker_type tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v(1000);
 | 
			
		||||
        for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
                it != v.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
            iterator r1 = x.insert(x.begin(), *it);
 | 
			
		||||
@@ -122,10 +123,10 @@ void insert_tests2(X* = 0)
 | 
			
		||||
        tracker_type tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v(100);
 | 
			
		||||
        for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
                it != v.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
            const_iterator r1 = x.insert(x_const.end(), *it);
 | 
			
		||||
@@ -148,10 +149,10 @@ void insert_tests2(X* = 0)
 | 
			
		||||
        tracker_type tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v(1000);
 | 
			
		||||
        for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
                it != v.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
            pos = x.insert(pos, *it);
 | 
			
		||||
@@ -173,10 +174,10 @@ void insert_tests2(X* = 0)
 | 
			
		||||
        tracker_type tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
        test::random_values<X> v(1000);
 | 
			
		||||
        for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
        for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
                it != v.end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
            float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
            x.insert(it, boost::next(it));
 | 
			
		||||
@@ -224,10 +225,10 @@ void map_tests(X* = 0)
 | 
			
		||||
    test::ordered<X> tracker = test::create_ordered(x);
 | 
			
		||||
 | 
			
		||||
    test::random_values<X> v(1000);
 | 
			
		||||
    for(typename test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
    for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
 | 
			
		||||
            it != v.end(); ++it)
 | 
			
		||||
    {
 | 
			
		||||
        typename X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
 | 
			
		||||
        float b = x.max_load_factor();
 | 
			
		||||
 | 
			
		||||
        x[it->first] = it->second;
 | 
			
		||||
@@ -296,6 +297,5 @@ int main()
 | 
			
		||||
    associative_insert_range_test((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
 | 
			
		||||
    associative_insert_range_test((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
 | 
			
		||||
    associative_insert_range_test((boost::unordered_multimap<test::equivalent_object, test::equivalent_object, test::hash, test::equal_to, test::allocator<test::equivalent_object> >*) 0);
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,10 +39,10 @@ void insert_test(X*, float mlf)
 | 
			
		||||
 | 
			
		||||
    test::random_values<X> values(1000);
 | 
			
		||||
 | 
			
		||||
    for(typename test::random_values<X>::const_iterator
 | 
			
		||||
    for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
 | 
			
		||||
            it = values.begin(), end = values.end(); it != end; ++it)
 | 
			
		||||
    {
 | 
			
		||||
        typename X::size_type old_size = x.size(),
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(),
 | 
			
		||||
                 old_bucket_count = x.bucket_count();
 | 
			
		||||
        x.insert(*it);
 | 
			
		||||
        if(old_size + 1 < b * old_bucket_count)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
test::seed_t seed(2974);
 | 
			
		||||
 | 
			
		||||
template <class X>
 | 
			
		||||
bool postcondition(X const& x, typename X::size_type n)
 | 
			
		||||
bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
 | 
			
		||||
{
 | 
			
		||||
    return x.bucket_count() > x.size() / x.max_load_factor() && x.bucket_count() >= n;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -51,8 +51,8 @@ void simple_test(X const& a)
 | 
			
		||||
        BOOST_TEST(b.empty());
 | 
			
		||||
        BOOST_TEST(equivalent(c));
 | 
			
		||||
        b.swap(c);
 | 
			
		||||
        BOOST_TEST(b.empty());
 | 
			
		||||
        BOOST_TEST(equivalent(c));
 | 
			
		||||
        BOOST_TEST(c.empty());
 | 
			
		||||
        BOOST_TEST(equivalent(b));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
@@ -68,7 +68,7 @@ void simple_test(X const& a)
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST(a.size() ==
 | 
			
		||||
                (typename X::size_type) std::distance(a.begin(), a.end()));
 | 
			
		||||
                (BOOST_DEDUCED_TYPENAME X::size_type) std::distance(a.begin(), a.end()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
@@ -84,20 +84,43 @@ void simple_test(X const& a)
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  	using namespace std;
 | 
			
		||||
   	srand(14878);
 | 
			
		||||
 | 
			
		||||
    std::cout<<"Test unordered_set.\n";
 | 
			
		||||
    boost::unordered_set<int> set;
 | 
			
		||||
    simple_test(set);
 | 
			
		||||
    
 | 
			
		||||
    set.insert(1); set.insert(2); set.insert(1456);
 | 
			
		||||
    simple_test(set);
 | 
			
		||||
 | 
			
		||||
    std::cout<<"Test unordered_multiset.\n";
 | 
			
		||||
    boost::unordered_multiset<int> multiset;
 | 
			
		||||
    simple_test(multiset);
 | 
			
		||||
    
 | 
			
		||||
    for(int i1 = 0; i1 < 1000; ++i1) {
 | 
			
		||||
    	int count = rand() % 10, index = rand();
 | 
			
		||||
    	for(int j = 0; j < count; ++j)
 | 
			
		||||
	    	multiset.insert(index);
 | 
			
		||||
    }
 | 
			
		||||
    simple_test(multiset);
 | 
			
		||||
    
 | 
			
		||||
    std::cout<<"Test unordered_map.\n";
 | 
			
		||||
    boost::unordered_map<int, int> map;
 | 
			
		||||
 | 
			
		||||
    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";
 | 
			
		||||
    boost::unordered_multimap<int, int> multimap;
 | 
			
		||||
 | 
			
		||||
    for(int i3 = 0; i3 < 1000; ++i3) {
 | 
			
		||||
    	int count = rand() % 10, index = rand();
 | 
			
		||||
    	for(int j = 0; j < count; ++j)
 | 
			
		||||
	    	multimap.insert(std::pair<const int, int>(index, rand()));
 | 
			
		||||
    }
 | 
			
		||||
    simple_test(multimap);
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
 
 | 
			
		||||
@@ -61,9 +61,9 @@ void swap_tests2(X* ptr = 0)
 | 
			
		||||
{
 | 
			
		||||
    swap_tests1(ptr);
 | 
			
		||||
 | 
			
		||||
    typedef typename X::hasher hasher;
 | 
			
		||||
    typedef typename X::key_equal key_equal;
 | 
			
		||||
    typedef typename X::allocator_type allocator_type;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::hasher hasher;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::key_equal key_equal;
 | 
			
		||||
    typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        X x(0, hasher(1), key_equal(1));
 | 
			
		||||
 
 | 
			
		||||
@@ -7,51 +7,52 @@
 | 
			
		||||
#include <boost/unordered_map.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
struct count_copies
 | 
			
		||||
{
 | 
			
		||||
    static int count;
 | 
			
		||||
    count_copies() { ++count; }
 | 
			
		||||
    count_copies(count_copies const&) { ++count; }
 | 
			
		||||
private:
 | 
			
		||||
    count_copies& operator=(count_copies const&);
 | 
			
		||||
};
 | 
			
		||||
namespace test {
 | 
			
		||||
    struct count_copies
 | 
			
		||||
    {
 | 
			
		||||
        static int count;
 | 
			
		||||
        count_copies() { ++count; }
 | 
			
		||||
        count_copies(count_copies const&) { ++count; }
 | 
			
		||||
    private:
 | 
			
		||||
       count_copies& operator=(count_copies const&);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    bool operator==(test::count_copies const&, test::count_copies const&) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
 | 
			
		||||
namespace boost {
 | 
			
		||||
#else
 | 
			
		||||
namespace test {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
std::size_t hash_value(count_copies const&) {
 | 
			
		||||
    return 0;
 | 
			
		||||
    std::size_t hash_value(test::count_copies const&) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
 | 
			
		||||
namespace test {
 | 
			
		||||
    int count_copies::count;
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    void unnecessary_copy_test(T*)
 | 
			
		||||
    {
 | 
			
		||||
        count_copies::count = 0;
 | 
			
		||||
        T x;
 | 
			
		||||
        BOOST_DEDUCED_TYPENAME T::value_type a;
 | 
			
		||||
        BOOST_TEST(count_copies::count == 1);
 | 
			
		||||
        x.insert(a);
 | 
			
		||||
        BOOST_TEST(count_copies::count == 2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool operator==(count_copies const&, count_copies const&) {
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int count_copies::count;
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void unnecessary_copy_test(T*)
 | 
			
		||||
{
 | 
			
		||||
    count_copies::count = 0;
 | 
			
		||||
    T x;
 | 
			
		||||
    typename T::value_type a;
 | 
			
		||||
    BOOST_TEST(count_copies::count == 1);
 | 
			
		||||
    x.insert(a);
 | 
			
		||||
    BOOST_TEST(count_copies::count == 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    unnecessary_copy_test((boost::unordered_set<count_copies>*) 0);
 | 
			
		||||
    unnecessary_copy_test((boost::unordered_multiset<count_copies>*) 0);
 | 
			
		||||
    unnecessary_copy_test((boost::unordered_map<int, count_copies>*) 0);
 | 
			
		||||
    unnecessary_copy_test((boost::unordered_multimap<int, count_copies>*) 0);
 | 
			
		||||
    test::unnecessary_copy_test((boost::unordered_set<test::count_copies>*) 0);
 | 
			
		||||
    test::unnecessary_copy_test((boost::unordered_multiset<test::count_copies>*) 0);
 | 
			
		||||
    test::unnecessary_copy_test((boost::unordered_map<int, test::count_copies>*) 0);
 | 
			
		||||
    test::unnecessary_copy_test((boost::unordered_multimap<int, test::count_copies>*) 0);
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user