1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com> 3 // 4 // Distributed under the Boost Software License, Version 1.0 5 // See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt 7 // 8 // See http://boostorg.github.com/compute for more information. 9 //---------------------------------------------------------------------------// 10 11 #ifndef BOOST_COMPUTE_FUNCTIONAL_HASH_HPP 12 #define BOOST_COMPUTE_FUNCTIONAL_HASH_HPP 13 14 #include <boost/compute/function.hpp> 15 #include <boost/compute/types/fundamental.hpp> 16 17 namespace boost { 18 namespace compute { 19 namespace detail { 20 21 template<class Key> make_hash_function_name()22std::string make_hash_function_name() 23 { 24 return std::string("boost_hash_") + type_name<Key>(); 25 } 26 27 template<class Key> make_hash_function_source()28inline std::string make_hash_function_source() 29 { 30 std::stringstream source; 31 source << "inline ulong " << make_hash_function_name<Key>() 32 << "(const " << type_name<Key>() << " x)\n" 33 << "{\n" 34 // note we reinterpret the argument as a 32-bit uint and 35 // then promote it to a 64-bit ulong for the result type 36 << " ulong a = as_uint(x);\n" 37 << " a = (a ^ 61) ^ (a >> 16);\n" 38 << " a = a + (a << 3);\n" 39 << " a = a ^ (a >> 4);\n" 40 << " a = a * 0x27d4eb2d;\n" 41 << " a = a ^ (a >> 15);\n" 42 << " return a;\n" 43 << "}\n"; 44 return source.str(); 45 } 46 47 template<class Key> 48 struct hash_impl 49 { 50 typedef Key argument_type; 51 typedef ulong_ result_type; 52 hash_implboost::compute::detail::hash_impl53 hash_impl() 54 : m_function("") 55 { 56 m_function = make_function_from_source<result_type(argument_type)>( 57 make_hash_function_name<argument_type>(), 58 make_hash_function_source<argument_type>() 59 ); 60 } 61 62 template<class Arg> 63 invoked_function<result_type, boost::tuple<Arg> > operator ()boost::compute::detail::hash_impl64 operator()(const Arg &arg) const 65 { 66 return m_function(arg); 67 } 68 69 function<result_type(argument_type)> m_function; 70 }; 71 72 } // end detail namespace 73 74 /// The hash function returns a hash value for the input value. 75 /// 76 /// The return type is \c ulong_ (the OpenCL unsigned long type). 77 template<class Key> struct hash; 78 79 /// \internal_ 80 template<> struct hash<int_> : detail::hash_impl<int_> { }; 81 82 /// \internal_ 83 template<> struct hash<uint_> : detail::hash_impl<uint_> { }; 84 85 /// \internal_ 86 template<> struct hash<float_> : detail::hash_impl<float_> { }; 87 88 } // end compute namespace 89 } // end boost namespace 90 91 #endif // BOOST_COMPUTE_FUNCTIONAL_HASH_HPP 92