| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | [/ 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) ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [section:hash_equality Equality Predicates and Hash Functions] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | While the associative containers use an ordering relation to specify how the | 
					
						
							|  |  |  | elements are stored, the unordered associative containers use an equality | 
					
						
							| 
									
										
										
										
											2007-06-20 20:47:51 +00:00
										 |  |  | predicate and a hash function. For example, [classref boost::unordered_set] | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | is declared as: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename Value, | 
					
						
							|  |  |  |            typename Hash = ``[classref boost::hash]``<Value>,  | 
					
						
							|  |  |  |            typename Pred = std::equal_to<Value>,  | 
					
						
							|  |  |  |            typename Alloc = std::allocator<Value> >  | 
					
						
							|  |  |  |     class ``[classref boost::unordered_set unordered_set]``; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The hash function comes first as you might want to change the hash function | 
					
						
							|  |  |  | but not the equality predicate, while if you were to change the behaviour | 
					
						
							|  |  |  | of the equality predicate you would have to change the hash function to match | 
					
						
							| 
									
										
										
										
											2007-06-20 20:47:51 +00:00
										 |  |  | it.  So, if you wanted to use the | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | [@http://www.isthe.com/chongo/tech/comp/fnv/ FNV-1 hash] you could write: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ``[classref boost::unordered_set]``<std::string, hash::fnv_1> words; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An example implementation of FNV-1, and some other hash functions are supplied | 
					
						
							|  |  |  | in the examples directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Alternatively, you might wish to use a different equality function. If so, make | 
					
						
							| 
									
										
										
										
											2007-06-20 20:47:51 +00:00
										 |  |  | sure you use a hash function that matches it. So to implement a | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | case-insensitive dictionary: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-27 21:08:54 +00:00
										 |  |  | [import src_code/insensitive.cpp]  | 
					
						
							|  |  |  | [case_insensitive_functions]  | 
					
						
							|  |  |  | [case_insensitive_dictionary]  | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-20 20:47:51 +00:00
										 |  |  | A more generic version is available at: | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | [@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [h2 Custom Types] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Similarly, a custom hash function can be used for custom types: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct point { | 
					
						
							|  |  |  |         int x; | 
					
						
							|  |  |  |         int y; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool operator==(point const& p1, point const& p2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return p1.x == p2.x && p1.y == p2.y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct point_hash | 
					
						
							|  |  |  |         : std::unary_function<point, std::size_t> | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::size_t operator()(point const& p) const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             std::size_t seed = 0; | 
					
						
							|  |  |  |             boost::hash_combine(seed, p.x); | 
					
						
							|  |  |  |             boost::hash_combine(seed, p.y); | 
					
						
							|  |  |  |             return seed; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     boost::unordered_multiset<point, std::equal_to<point>, point_hash> | 
					
						
							|  |  |  |         points; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-15 23:36:33 +00:00
										 |  |  | Although, customising Boost.Hash is probably a better solution: | 
					
						
							| 
									
										
										
										
											2007-05-31 22:32:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     struct point { | 
					
						
							|  |  |  |         int x; | 
					
						
							|  |  |  |         int y; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool operator==(point const& p1, point const& p2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return p1.x == p2.x && p1.y == p2.y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::size_t hash_value(point const& x) { | 
					
						
							|  |  |  |         std::size_t seed = 0; | 
					
						
							|  |  |  |         boost::hash_combine(seed, p.x); | 
					
						
							|  |  |  |         boost::hash_combine(seed, p.y); | 
					
						
							|  |  |  |         return seed; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Now the default functions work. | 
					
						
							|  |  |  |     boost::unordered_multiset<point> points; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See the Boost.Hash documentation for more detail on how to do this. Remember | 
					
						
							|  |  |  | that it relies on extensions to the draft standard - so it won't work on other | 
					
						
							|  |  |  | implementations of the unordered associative containers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [table Methods for accessing the hash and equality functions. | 
					
						
							|  |  |  |     [[Method] [Description]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [``hasher hash_function() const``] | 
					
						
							|  |  |  |         [Returns the container's hash function.] | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         [``key_equal key_eq() const``] | 
					
						
							|  |  |  |         [Returns the container's key equality function.] | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [endsect] |