// 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 #include #include namespace test { template 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 static typename Container::key_type const& get_key(std::pair const& x) { return x.first; } static typename Container::value_type const& get_mapped(typename Container::key_type const& x) { return x; } template static M const& get_mapped(std::pair const& x) { return x.second; } }; template struct random_values : public accessors { typedef accessors base; typedef typename non_const_value_type::type value_type; typedef typename Container::key_type key_type; std::vector values_; typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; explicit random_values(std::size_t count) { values_.reserve(count); std::generate_n(std::back_inserter(values_), count, test::generator()); } 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 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 bool operator()(std::pair 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 static key_matcher1 key_match(std::pair const& x) { return key_matcher1(x.first); } template iterator find(K const& x) { return std::find_if(values_.begin(), values_.end(), key_match(x)); } template std::size_t count(K const& x) { return std::count_if(values_.begin(), values_.end(), key_match(x)); } template std::size_t key_count(K const& x) { if(has_unique_keys::value) return find(x) != values_.end(); else return count(x); } static bool is_unique() { return has_unique_keys::value; } }; template struct sorted_random_values : public random_values { typedef random_values 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 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 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 std::size_t count(K const& x) { std::pair range = std::equal_range(this->begin(), this->end(), x, key_compare()); return range.second - range.first; } template std::size_t key_count(K const& x) { if(has_unique_keys::value) return find(x) != this->end(); else return count(x); } }; } #endif