// Copyright 2017, 2018, 2024 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include #include #include template void test_identity() { using boost::hash2::get_integral_result; using R = typename Hash::result_type; Hash h; Hash h2( h ); for( int i = 0; i < 1024; ++i ) { R r = h.result(); R t = get_integral_result( h2 ); BOOST_TEST_EQ( t, r ); } } template std::size_t test_sample() { using boost::hash2::get_integral_result; std::set dist; for( unsigned i = 0; i <= std::numeric_limits::max(); ++i ) { T t1 = static_cast( i ); Hash h; boost::hash2::hash_append( h, {}, t1 ); T t2 = get_integral_result( h ); dist.insert( t2 ); } return dist.size(); } using boost::hash2::fnv1a_32; using boost::hash2::fnv1a_64; struct fnv1a_16: private fnv1a_32 { using result_type = std::uint16_t; using fnv1a_32::update; result_type result() { std::uint32_t r = fnv1a_32::result(); return static_cast( r ^ ( r >> 16 ) ); } }; struct fnv1a_8: private fnv1a_16 { using result_type = std::uint8_t; using fnv1a_16::update; result_type result() { std::uint16_t r = fnv1a_16::result(); return static_cast( r ^ ( r >> 8 ) ); } }; int main() { test_identity(); // EV(256 samples in 256 buckets) = 162 (256 * (1-e^-1)), stddev ~= 7.7 (sqrt(256) * 0.482) BOOST_TEST_EQ( (test_sample()), 168u ); // get_integral_result is identity BOOST_TEST_GE( (test_sample()), 154u ); BOOST_TEST_GE( (test_sample()), 154u ); BOOST_TEST_GE( (test_sample()), 154u ); test_identity(); // EV(65536 samples in 65536 buckets) = 41427 (65536 * (1-e^-1)), stddev ~= 123.4 (sqrt(65536) * 0.482) BOOST_TEST_EQ( (test_sample()), 40718u ); // get_integral_result is identity BOOST_TEST_GE( (test_sample()), 41303u ); BOOST_TEST_GE( (test_sample()), 41303u ); return boost::report_errors(); }