Utilities - Tuple hash computations
This commit is contained in:
parent
3889efde67
commit
8a19374d3f
2 changed files with 77 additions and 3 deletions
|
@ -376,6 +376,42 @@ inline uint32_t ComputeHash( std::pair< T1 , T2 > const& item )
|
||||||
return hv;
|
return hv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursive template that will hash each tuple element starting from
|
||||||
|
// the last one.
|
||||||
|
template< typename Tuple , size_t Index = std::tuple_size< Tuple >::value - 1 >
|
||||||
|
struct T_TupleHashHelper_
|
||||||
|
{
|
||||||
|
static void apply( uint32_t& hashValue , Tuple const& t )
|
||||||
|
{
|
||||||
|
T_TupleHashHelper_< Tuple , Index - 1 >::apply( hashValue , t );
|
||||||
|
CombineHash( hashValue , std::get< Index >( t ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Specialize for the first element, as it must not recurse.
|
||||||
|
template< typename Tuple >
|
||||||
|
struct T_TupleHashHelper_< Tuple , 0 >
|
||||||
|
{
|
||||||
|
static void apply( uint32_t& hashValue , Tuple const& t )
|
||||||
|
{
|
||||||
|
CombineHash( hashValue , std::get< 0 >( t ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename... Types >
|
||||||
|
inline uint32_t ComputeHash( std::tuple< Types... > const& item )
|
||||||
|
{
|
||||||
|
uint32_t hv = 0;
|
||||||
|
T_TupleHashHelper_< std::tuple< Types... > >::apply( hv , item );
|
||||||
|
return hv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specialize the function for empty tuples
|
||||||
|
template< >
|
||||||
|
inline uint32_t ComputeHash( std::tuple< > const& )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*= PRIVATE IMPLEMENTATION BASE ==============================================*/
|
/*= PRIVATE IMPLEMENTATION BASE ==============================================*/
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ class ComputeHashTest : public CppUnit::TestFixture
|
||||||
CPPUNIT_TEST( testInt64 );
|
CPPUNIT_TEST( testInt64 );
|
||||||
CPPUNIT_TEST( testStructDefault );
|
CPPUNIT_TEST( testStructDefault );
|
||||||
CPPUNIT_TEST( testPair );
|
CPPUNIT_TEST( testPair );
|
||||||
|
|
||||||
|
CPPUNIT_TEST( testTupleEmpty );
|
||||||
|
CPPUNIT_TEST( testTupleOne );
|
||||||
|
CPPUNIT_TEST( testTuplePair );
|
||||||
|
CPPUNIT_TEST( testTupleMore );
|
||||||
CPPUNIT_TEST_SUITE_END( );
|
CPPUNIT_TEST_SUITE_END( );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -23,6 +28,11 @@ public:
|
||||||
void testInt64( );
|
void testInt64( );
|
||||||
void testStructDefault( );
|
void testStructDefault( );
|
||||||
void testPair( );
|
void testPair( );
|
||||||
|
|
||||||
|
void testTupleEmpty( );
|
||||||
|
void testTupleOne( );
|
||||||
|
void testTuplePair( );
|
||||||
|
void testTupleMore( );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,10 +89,38 @@ void ComputeHashTest::testStructDefault( )
|
||||||
|
|
||||||
void ComputeHashTest::testPair( )
|
void ComputeHashTest::testPair( )
|
||||||
{
|
{
|
||||||
auto p{ std::make_pair< uint8_t , uint32_t >( 12 , 128 ) };
|
const auto p{ std::make_pair< uint8_t , uint32_t >( 12 , 128 ) };
|
||||||
|
|
||||||
uint32_t hv = 0x9e3779b9 + 12;
|
uint32_t hv = 0x9e3779b9 + 12;
|
||||||
hv = 128 + 0x9e3779b9 + ( hv << 6 ) + ( hv >> 2 );
|
hv = 128 + 0x9e3779b9 + ( hv << 6 ) + ( hv >> 2 );
|
||||||
|
|
||||||
CPPUNIT_ASSERT_EQUAL( hv , ComputeHash( p ) );
|
CPPUNIT_ASSERT_EQUAL( hv , ComputeHash( p ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void ComputeHashTest::testTupleEmpty( )
|
||||||
|
{
|
||||||
|
const std::tuple< > t{};
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 0u , ComputeHash( t ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeHashTest::testTupleOne( )
|
||||||
|
{
|
||||||
|
const std::tuple< uint8_t > t{ 12 };
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 0x9e3779b9 + 12u , ComputeHash( t ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeHashTest::testTuplePair( )
|
||||||
|
{
|
||||||
|
const auto p{ std::make_pair< uint8_t , uint32_t >( 12 , 128 ) };
|
||||||
|
const auto t{ std::make_tuple< uint8_t , uint32_t >( 12 , 128 ) };
|
||||||
|
CPPUNIT_ASSERT_EQUAL( ComputeHash( p ) , ComputeHash( t ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeHashTest::testTupleMore( )
|
||||||
|
{
|
||||||
|
const auto p{ std::make_pair< uint8_t , uint32_t >( 12 , 128 ) };
|
||||||
|
const auto t{ std::make_tuple< uint8_t , uint32_t , uint8_t >( 12 , 128 , 92 ) };
|
||||||
|
uint32_t hv = ComputeHash( p );
|
||||||
|
CombineHash( hv , uint8_t( 92 ) );
|
||||||
|
CPPUNIT_ASSERT_EQUAL( hv , ComputeHash( t ) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue