| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-27 23:38:01 +00:00
										 |  |  | // Copyright 2005-2008 Daniel James.
 | 
					
						
							| 
									
										
										
										
											2006-07-01 22:31:26 +00:00
										 |  |  | // 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)
 | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined(BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER)
 | 
					
						
							|  |  |  | #define BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/unordered_map.hpp>
 | 
					
						
							|  |  |  | #include <boost/unordered_set.hpp>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | #include "./metafunctions.hpp"
 | 
					
						
							| 
									
										
										
										
											2006-06-18 13:24:38 +00:00
										 |  |  | #include "./fwd.hpp"
 | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace test | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-06-11 19:42:55 +00:00
										 |  |  |     template <class T1, class T2> | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |     bool equivalent_impl(T1 const& x, T2 const& y, base_type) { | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |         return x == y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <class T> | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |     bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&, derived_type) { | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <class T> | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |     bool equivalent_impl(std::equal_to<T> const&, std::equal_to<T> const&, derived_type) { | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-21 17:14:11 +00:00
										 |  |  |     template <class T1, class T2, class T3, class T4> | 
					
						
							|  |  |  |     bool equivalent_impl(std::pair<T1, T2> const& x1, | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |             std::pair<T3, T4> const& x2, derived_type) { | 
					
						
							|  |  |  |         return equivalent_impl(x1.first, x2.first, derived) && | 
					
						
							|  |  |  |             equivalent_impl(x1.second, x2.second, derived); | 
					
						
							| 
									
										
										
										
											2006-05-21 17:14:11 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct equivalent_type { | 
					
						
							|  |  |  |         template <class T1, class T2> | 
					
						
							|  |  |  |         bool operator()(T1 const& x, T2 const& y) { | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |             return equivalent_impl(x, y, derived); | 
					
						
							| 
									
										
										
										
											2006-05-21 17:14:11 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     namespace { | 
					
						
							|  |  |  |         equivalent_type equivalent; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |     template <class Container> | 
					
						
							|  |  |  |     class unordered_equivalence_tester | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-01-10 22:30:46 +00:00
										 |  |  |         BOOST_DEDUCED_TYPENAME Container::size_type size_; | 
					
						
							|  |  |  |         BOOST_DEDUCED_TYPENAME Container::hasher hasher_; | 
					
						
							|  |  |  |         BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_; | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |         float max_load_factor_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-10 22:30:46 +00:00
										 |  |  |         typedef BOOST_DEDUCED_TYPENAME non_const_value_type<Container>::type value_type; | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |         std::vector<value_type> values_; | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         unordered_equivalence_tester(Container const &x) | 
					
						
							|  |  |  |             : size_(x.size()), | 
					
						
							|  |  |  |             hasher_(x.hash_function()), key_equal_(x.key_eq()), | 
					
						
							|  |  |  |             max_load_factor_(x.max_load_factor()), | 
					
						
							|  |  |  |             values_() | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Can't initialise values_ straight from x because of Visual C++ 6
 | 
					
						
							|  |  |  |             values_.reserve(x.size()); | 
					
						
							|  |  |  |             std::copy(x.begin(), x.end(), std::back_inserter(values_)); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             std::sort(values_.begin(), values_.end()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool operator()(Container const& x) const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if(!((size_ == x.size()) && | 
					
						
							| 
									
										
										
										
											2006-06-12 23:30:46 +00:00
										 |  |  |                 (test::equivalent(hasher_, x.hash_function())) && | 
					
						
							|  |  |  |                 (test::equivalent(key_equal_, x.key_eq())) && | 
					
						
							| 
									
										
										
										
											2006-05-17 17:19:16 +00:00
										 |  |  |                 (max_load_factor_ == x.max_load_factor()) && | 
					
						
							|  |  |  |                 (values_.size() == x.size()))) return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             std::vector<value_type> copy; | 
					
						
							|  |  |  |             copy.reserve(x.size()); | 
					
						
							|  |  |  |             std::copy(x.begin(), x.end(), std::back_inserter(copy)); | 
					
						
							|  |  |  |             std::sort(copy.begin(), copy.end()); | 
					
						
							|  |  |  |             return(std::equal(values_.begin(), values_.end(), copy.begin())); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         unordered_equivalence_tester(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |