#include #include #include #include #include #include #include #include using namespace mapbox::util; void test_singleton() { using V = variant; V singleton = 5; if (std::hash{}(singleton) != std::hash{}(5)) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } } void test_default_hashable() { using V = variant; V var; // Check int hashes var = 1; if (std::hash{}(var) != std::hash{}(1)) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } // Check double hashes var = 23.4; if (std::hash{}(var) != std::hash{}(23.4)) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } // Check string hashes var = std::string{"Hello, World!"}; if (std::hash{}(var) != std::hash{}("Hello, World!")) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } } struct Hashable { static const constexpr auto const_hash = 5; }; namespace std { template <> struct hash { std::size_t operator()(const Hashable&) const noexcept { return Hashable::const_hash; } }; } void test_custom_hasher() { using V = variant; V var; var = Hashable{}; if (std::hash{}(var) != Hashable::const_hash) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } } void test_hashable_in_container() { using V = variant; // won't compile if V is not Hashable std::unordered_set vs; vs.insert(1); vs.insert(2.3); vs.insert("4"); } struct Empty { }; struct Node; using Tree = variant>; struct Node { Node(Tree left_, Tree right_) : left(std::move(left_)), right(std::move(right_)) {} Tree left = Empty{}; Tree right = Empty{}; }; namespace std { template <> struct hash { std::size_t operator()(const Empty&) const noexcept { return 3; } }; template <> struct hash { std::size_t operator()(const Node& n) const noexcept { return 5 + std::hash{}(n.left) + std::hash{}(n.right); } }; } void test_recursive_hashable() { Tree tree = Node{Node{Empty{}, Empty{}}, Empty{}}; if (std::hash{}(tree) != ((5 + (5 + (3 + 3))) + 3)) { std::cerr << "Expected variant hash to be the same as hash of its value\n"; std::exit(EXIT_FAILURE); } } int main() { test_singleton(); test_default_hashable(); test_custom_hasher(); test_hashable_in_container(); test_recursive_hashable(); }