81 lines
2.2 KiB
C++
81 lines
2.2 KiB
C++
|
#include "hash/table.hpp"
|
||
|
|
||
|
#include "tap.hpp"
|
||
|
#include "introspection.hpp"
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
/// Exhaustively test the table hash output for:
|
||
|
/// * uniqueness
|
||
|
/// * equal counts of bit values at each bit offset
|
||
|
template <typename ValueT>
|
||
|
void test_type (cruft::TAP::logger &tap)
|
||
|
{
|
||
|
// Exhaustively list the hash outputs for u08. The result is sorted
|
||
|
// because it simplifies upcoming tests and we don't care about mapping it
|
||
|
// back to the original values.
|
||
|
std::vector<ValueT> results;
|
||
|
std::iota (
|
||
|
std::begin (results),
|
||
|
std::end (results),
|
||
|
0
|
||
|
);
|
||
|
|
||
|
std::transform (
|
||
|
std::begin (results),
|
||
|
std::end (results),
|
||
|
std::begin (results),
|
||
|
cruft::hash::table<ValueT> {}
|
||
|
);
|
||
|
|
||
|
std::sort (std::begin (results), std::end (results));
|
||
|
|
||
|
// Ensure all values are unique.
|
||
|
{
|
||
|
auto const pos = std::adjacent_find (std::begin (results), std::end (results));
|
||
|
tap.expect (
|
||
|
pos == std::end (results),
|
||
|
"no equal elements, %!",
|
||
|
cruft::type_name<ValueT> ()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Ensure that at each bit offset we have equal numbers of high and low
|
||
|
// values across the table results.
|
||
|
{
|
||
|
bool success = true;
|
||
|
|
||
|
std::vector<int> bits;
|
||
|
for (std::size_t i = 0; i < sizeof (ValueT) * 8; ++i) {
|
||
|
bits.clear ();
|
||
|
|
||
|
for (auto const v: results)
|
||
|
bits.push_back ((v >> i) & 0x1);
|
||
|
|
||
|
auto const zeros = std::count (std::begin (bits), std::end (bits), 0);
|
||
|
auto const ones = std::count (std::begin (bits), std::end (bits), 1);
|
||
|
if (zeros != ones) {
|
||
|
success = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
tap.expect (
|
||
|
success,
|
||
|
"equal counts at bit positions, %!",
|
||
|
cruft::type_name<ValueT> ()
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
int main ()
|
||
|
{
|
||
|
cruft::TAP::logger tap;
|
||
|
test_type<u08> (tap);
|
||
|
test_type<u16> (tap);
|
||
|
test_type<u32> (tap);
|
||
|
test_type<u64> (tap);
|
||
|
return tap.status ();
|
||
|
}
|