#include "kblib/hash.h" #include "catch.hpp" #include #include #include #include struct has_padding { char c; int i; }; struct empty_t {}; static_assert( kblib::is_linear_container_v< std:: string> and kblib::is_contiguous_v and kblib::is_trivially_hashable_v and kblib::is_trivially_hashable_v, ""); static_assert(kblib::asserts::is_trivial_container>, ""); TEST_CASE("FNV_hash") { (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash::iterator>{}({}); (void)kblib::FNV_hash::iterator>{}({}); (void)kblib::FNV_hash::iterator>{}({}); std::unordered_map, std::vector>, kblib::FNV_hash>> test_map; using map_t = kblib::hash_map, std::vector>>; static_assert(std::is_same::value, ""); KBLIB_UNUSED kblib::FNV_hash> test_hash1; KBLIB_UNUSED kblib::FNV_hash> test_hash1a; KBLIB_UNUSED kblib::FNV_hash> test_hash1b; KBLIB_UNUSED kblib::FNV_hash, int>> test_hash1c; KBLIB_UNUSED kblib::FNV_hash, std::vector>>> test_hash2; KBLIB_UNUSED kblib::FNV_hash, 4>> test_hash3; KBLIB_UNUSED auto call = &decltype(test_hash1)::operator(); // std::hash< // std::unordered_map>, // std::hash>> // std_hash; using namespace kblib::literals; kblib::FNV_hash h_i; static_assert(3452452_fnv64 == h_i(3452452ull), "hash literal and FNH_hash don't agree"); CHECK(kblib::FNV_hash{}(1000) == 0x2fa9eaf82259d71cu); (void)kblib::FNV_hash>{}({}); (void)kblib::FNV_hash>{}({}); // fails because of padding: // kblib::FNV_hash>{}({}); // fails because of unorderedness: // kblib::FNV_hash>{}({}); kblib::FNV_hash test_hash4; CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i)); #if KBLIB_USE_CXX17 kblib::FNV_hash> test_opt_hash; (void)test_opt_hash(std::nullopt); (void)test_opt_hash(42); CHECK(test_opt_hash(42) == kblib::FNV_hash{}(42)); std::variant var(std::in_place_index<1>, 42); kblib::FNV_hash test_var_hash; CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash{}(42)); CHECK_FALSE(test_var_hash(var) == test_var_hash(decltype(var){std::in_place_index<0>, 42})); #endif } TEST_CASE("FNV_hash (32 bit)") { (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash{}({}); (void)kblib::FNV_hash::iterator, std::uint32_t>{}({}); (void)kblib::FNV_hash::iterator, std::uint32_t>{}({}); (void)kblib::FNV_hash::iterator, std::uint32_t>{}({}); KBLIB_UNUSED kblib::FNV_hash, std::uint32_t> test_hash1; KBLIB_UNUSED kblib::FNV_hash, std::uint32_t> test_hash1a; KBLIB_UNUSED kblib::FNV_hash, std::uint32_t> test_hash1b; KBLIB_UNUSED kblib::FNV_hash, int>, std::uint32_t> test_hash1c; KBLIB_UNUSED kblib::FNV_hash, std::vector>>, std::uint32_t> test_hash2; KBLIB_UNUSED kblib::FNV_hash, 4>, std::uint32_t> test_hash3; KBLIB_UNUSED auto call = &decltype(test_hash1)::operator(); // std::hash< // std::unordered_map>, // std::hash>> // std_hash; using namespace kblib::literals; kblib::FNV_hash h_i; static_assert(3452452_fnv32 == h_i(3452452u), "hash literal and FNH_hash don't agree"); CHECK(kblib::FNV_hash{}(1000) == 0xf49c691cu); (void)kblib::FNV_hash, std::uint32_t>{}({}); (void)kblib::FNV_hash, std::uint32_t>{}({}); // fails because of padding: // kblib::FNV_hash>{}({}); // fails because of unorderedness: // kblib::FNV_hash>{}({}); kblib::FNV_hash test_hash4; CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i)); #if KBLIB_USE_CXX17 kblib::FNV_hash, std::uint32_t> test_opt_hash; (void)test_opt_hash(std::nullopt); (void)test_opt_hash(42); CHECK(test_opt_hash(42) == kblib::FNV_hash{}(42)); std::variant var(std::in_place_index<1>, 42); kblib::FNV_hash test_var_hash; CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash{}(42)); CHECK_FALSE(test_var_hash(var) == test_var_hash(decltype(var){std::in_place_index<0>, 42})); #endif }