diff --git a/include/ebcl/Utilities.hh b/include/ebcl/Utilities.hh index 86ba32b..c8c1b8d 100644 --- a/include/ebcl/Utilities.hh +++ b/include/ebcl/Utilities.hh @@ -466,6 +466,11 @@ struct T_HashFunction template< typename T > uint32_t ComputeHash( T const& item ); +// CombineHash( &hv , T ) - Helper that consolidates multiple hashes into a +// single value. +template< typename T > +void CombineHash( uint32_t& hashValue , T const& item ); + // Helper macros to declare and define specialised hash functions. #define M_DECLARE_HASH( Type ) \ template< > \ diff --git a/include/ebcl/inline/Utilities.hh b/include/ebcl/inline/Utilities.hh index 08d8c37..49688d2 100644 --- a/include/ebcl/inline/Utilities.hh +++ b/include/ebcl/inline/Utilities.hh @@ -315,6 +315,12 @@ inline uint32_t ComputeHash( T const& item ) return T_HashFunction< T >::hash( item ); } +template< typename T > +inline void CombineHash( uint32_t& hashValue , T const& item ) +{ + hashValue = ComputeHash( item ) + 0x9e3779b9 + ( hashValue << 6 ) + ( hashValue >> 2 ); +} + /*----------------------------------------------------------------------------*/ // Hash function specializations for data sizes 1, 2, 4 and 8. @@ -358,6 +364,18 @@ struct T_HashFunction< T , 8 > } }; +/*----------------------------------------------------------------------------*/ +// Hash functions for pairs and tuples + +template< typename T1 , typename T2 > +inline uint32_t ComputeHash( std::pair< T1 , T2 > const& item ) +{ + uint32_t hv{ 0 }; + CombineHash( hv , item.first ); + CombineHash( hv , item.second ); + return hv; +} + /*= PRIVATE IMPLEMENTATION BASE ==============================================*/ diff --git a/tests/hash-functions.cc b/tests/hash-functions.cc index 4ce5373..4e11aa9 100644 --- a/tests/hash-functions.cc +++ b/tests/hash-functions.cc @@ -13,6 +13,7 @@ class ComputeHashTest : public CppUnit::TestFixture CPPUNIT_TEST( testInt32 ); CPPUNIT_TEST( testInt64 ); CPPUNIT_TEST( testStructDefault ); + CPPUNIT_TEST( testPair ); CPPUNIT_TEST_SUITE_END( ); public: @@ -21,6 +22,7 @@ public: void testInt32( ); void testInt64( ); void testStructDefault( ); + void testPair( ); }; @@ -74,3 +76,13 @@ void ComputeHashTest::testStructDefault( ) CPPUNIT_ASSERT_EQUAL( uint32_t( HashData( test.meh , 16 ) ) , ComputeHash( test ) ); } + +void ComputeHashTest::testPair( ) +{ + auto p{ std::make_pair< uint8_t , uint32_t >( 12 , 128 ) }; + + uint32_t hv = 0x9e3779b9 + 12; + hv = 128 + 0x9e3779b9 + ( hv << 6 ) + ( hv >> 2 ); + + CPPUNIT_ASSERT_EQUAL( hv , ComputeHash( p ) ); +}