1 /////////////////////////////////////////////////////////////// 2 // Copyright 2012 John Maddock. Distributed under the Boost 3 // Software License, Version 1.0. (See accompanying file 4 // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt 5 6 #include <boost/multiprecision/cpp_int.hpp> 7 #include <boost/random.hpp> 8 #include <boost/functional/hash.hpp> 9 #include <unordered_set> 10 #include <city.h> 11 12 //[hash1 13 14 /*` 15 All of the types in this library support hashing via boost::hash or std::hash. 16 That means we can use multiprecision types directly in hashed containers such as std::unordered_set: 17 */ 18 //] 19 t1()20void t1() 21 { 22 //[hash2 23 using namespace boost::multiprecision; 24 using namespace boost::random; 25 26 mt19937 mt; 27 uniform_int_distribution<uint256_t> ui; 28 29 std::unordered_set<uint256_t> set; 30 // Put 1000 random values into the container: 31 for(unsigned i = 0; i < 1000; ++i) 32 set.insert(ui(mt)); 33 34 //] 35 } 36 37 //[hash3 38 39 /*` 40 Or we can define our own hash function, for example in this case based on 41 Google's CityHash: 42 */ 43 44 struct cityhash 45 { operator ()cityhash46 std::size_t operator()(const boost::multiprecision::uint256_t& val)const 47 { 48 // create a hash from all the limbs of the argument, this function is probably x64 specific, 49 // and requires that we access the internals of the data type: 50 std::size_t result = CityHash64(reinterpret_cast<const char*>(val.backend().limbs()), val.backend().size() * sizeof(val.backend().limbs()[0])); 51 // modify the returned hash based on sign: 52 return val < 0 ? ~result : result; 53 } 54 }; 55 56 //] 57 t2()58void t2() 59 { 60 //[hash4 61 62 /*`As before insert some values into a container, this time using our custom hasher:*/ 63 64 std::unordered_set<uint256_t, cityhash> set2; 65 for(unsigned i = 0; i < 1000; ++i) 66 set2.insert(ui(mt)); 67 68 //] 69 } 70 main()71int main() 72 { 73 t1(); 74 t2(); 75 return 0; 76 } 77 78