mirror of
				https://github.com/boostorg/unordered.git
				synced 2025-11-04 09:41:40 +01:00 
			
		
		
		
	
		
			
	
	
		
			204 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			204 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//  Copyright Daniel James 2005. Use, modification, and distribution are
							 | 
						||
| 
								 | 
							
								//  subject to the Boost Software License, Version 1.0. (See accompanying
							 | 
						||
| 
								 | 
							
								//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if !defined(BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER)
							 | 
						||
| 
								 | 
							
								#define BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "./generators.hpp"
							 | 
						||
| 
								 | 
							
								#include "./metafunctions.hpp"
							 | 
						||
| 
								 | 
							
								#include <vector>
							 | 
						||
| 
								 | 
							
								#include <algorithm>
							 | 
						||
| 
								 | 
							
								#include <iterator>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace test
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    template <class Container>
							 | 
						||
| 
								 | 
							
								    struct accessors
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // get_key
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // Given either the value_type or the key_type returns the key.
							 | 
						||
| 
								 | 
							
								        static typename Container::key_type const& 
							 | 
						||
| 
								 | 
							
								            get_key(typename Container::key_type const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return x;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K, class M>
							 | 
						||
| 
								 | 
							
								        static typename Container::key_type const&
							 | 
						||
| 
								 | 
							
								            get_key(std::pair<K, M> const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return x.first;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static typename Container::value_type const& 
							 | 
						||
| 
								 | 
							
								            get_mapped(typename Container::key_type const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return x;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K, class M>
							 | 
						||
| 
								 | 
							
								        static M const&
							 | 
						||
| 
								 | 
							
								            get_mapped(std::pair<K, M> const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return x.second;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class Container>
							 | 
						||
| 
								 | 
							
								    struct random_values : public accessors<Container>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef accessors<Container> base;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        typedef typename non_const_value_type<Container>::type value_type;
							 | 
						||
| 
								 | 
							
								        typedef typename Container::key_type key_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        std::vector<value_type> values_;
							 | 
						||
| 
								 | 
							
								        typedef typename std::vector<value_type>::iterator iterator;
							 | 
						||
| 
								 | 
							
								        typedef typename std::vector<value_type>::const_iterator const_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        explicit random_values(std::size_t count)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            values_.reserve(count);
							 | 
						||
| 
								 | 
							
								            std::generate_n(std::back_inserter(values_),
							 | 
						||
| 
								 | 
							
								                    count, test::generator<value_type>());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iterator begin() { return values_.begin(); }
							 | 
						||
| 
								 | 
							
								        iterator end() { return values_.end(); }
							 | 
						||
| 
								 | 
							
								        const_iterator begin() const { return values_.begin(); }
							 | 
						||
| 
								 | 
							
								        const_iterator end() const { return values_.end(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        value_type const& operator[](std::size_t i) const { return values_[i]; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        struct key_matcher0
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template <class X, class Y>
							 | 
						||
| 
								 | 
							
								            bool operator()(X const& x, Y const& y) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return base::get_key(x) == base::get_key(y);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // No, I don't know why didn't I just use bind.
							 | 
						||
| 
								 | 
							
								        struct key_matcher1
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            key_type x;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            key_matcher1(key_type const& x) : x(x) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            bool operator()(key_type const& y)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return x == y;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            template <class M>
							 | 
						||
| 
								 | 
							
								            bool operator()(std::pair<key_type, M> const& y)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return x == y.first;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static key_matcher0 key_match()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return key_matcher0();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static key_matcher1 key_match(key_type const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return key_matcher1(x);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class M>
							 | 
						||
| 
								 | 
							
								        static key_matcher1 key_match(std::pair<key_type, M> const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return key_matcher1(x.first);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        iterator find(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return std::find_if(values_.begin(), values_.end(), key_match(x));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        std::size_t count(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return std::count_if(values_.begin(), values_.end(),
							 | 
						||
| 
								 | 
							
								                    key_match(x));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        std::size_t key_count(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if(has_unique_keys<Container>::value)
							 | 
						||
| 
								 | 
							
								                return find(x) != values_.end();
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                return count(x);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static bool is_unique()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return has_unique_keys<Container>::value;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template <class Container>
							 | 
						||
| 
								 | 
							
								    struct sorted_random_values : public random_values<Container>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef random_values<Container> base;
							 | 
						||
| 
								 | 
							
								        typedef typename base::value_type value_type;
							 | 
						||
| 
								 | 
							
								        typedef typename base::key_type key_type;
							 | 
						||
| 
								 | 
							
								        typedef typename base::iterator iterator;
							 | 
						||
| 
								 | 
							
								        typedef typename base::const_iterator const_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        explicit sorted_random_values(std::size_t count)
							 | 
						||
| 
								 | 
							
								            : base(count)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            std::stable_sort(this->begin(), this->end());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        struct key_compare0
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            template <class X, class Y>
							 | 
						||
| 
								 | 
							
								            bool operator()(X const& x, Y const& y) const
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                return base::get_key(x) < base::get_key(y);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static key_compare0 key_compare()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return key_compare0();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        iterator find(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iterator pos = std::lower_bound(this->begin(), this->end(), x, key_compare());
							 | 
						||
| 
								 | 
							
								            return this->key_match()(x, *pos) ? pos : this->end();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        std::size_t count(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            std::pair<iterator, iterator> range =
							 | 
						||
| 
								 | 
							
								                std::equal_range(this->begin(), this->end(), x, key_compare());
							 | 
						||
| 
								 | 
							
								            return range.second - range.first;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template <class K>
							 | 
						||
| 
								 | 
							
								        std::size_t key_count(K const& x)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if(has_unique_keys<Container>::value)
							 | 
						||
| 
								 | 
							
								                return find(x) != this->end();
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								                return count(x);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |