aboutsummaryrefslogtreecommitdiff
path: root/test/std/utilities/variant/variant.hash/hash.pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/std/utilities/variant/variant.hash/hash.pass.cpp')
-rw-r--r--test/std/utilities/variant/variant.hash/hash.pass.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/test/std/utilities/variant/variant.hash/hash.pass.cpp b/test/std/utilities/variant/variant.hash/hash.pass.cpp
new file mode 100644
index 000000000000..d807a7c7e2ea
--- /dev/null
+++ b/test/std/utilities/variant/variant.hash/hash.pass.cpp
@@ -0,0 +1,124 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <variant>
+
+// template <class... Types> struct hash<variant<Types...>>;
+// template <> struct hash<monostate>;
+
+#include <cassert>
+#include <type_traits>
+#include <variant>
+
+#include "test_macros.h"
+#include "variant_test_helpers.hpp"
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+namespace std {
+template <> struct hash<::MakeEmptyT> {
+ size_t operator()(const ::MakeEmptyT &) const {
+ assert(false);
+ return 0;
+ }
+};
+}
+#endif
+
+void test_hash_variant() {
+ {
+ using V = std::variant<int, long, int>;
+ using H = std::hash<V>;
+ const V v(std::in_place_index<0>, 42);
+ const V v_copy = v;
+ V v2(std::in_place_index<0>, 100);
+ const H h{};
+ assert(h(v) == h(v));
+ assert(h(v) != h(v2));
+ assert(h(v) == h(v_copy));
+ {
+ ASSERT_SAME_TYPE(decltype(h(v)), std::size_t);
+ static_assert(std::is_copy_constructible<H>::value, "");
+ }
+ }
+ {
+ using V = std::variant<std::monostate, int, long, const char *>;
+ using H = std::hash<V>;
+ const char *str = "hello";
+ const V v0;
+ const V v0_other;
+ const V v1(42);
+ const V v1_other(100);
+ V v2(100l);
+ V v2_other(999l);
+ V v3(str);
+ V v3_other("not hello");
+ const H h{};
+ assert(h(v0) == h(v0));
+ assert(h(v0) == h(v0_other));
+ assert(h(v1) == h(v1));
+ assert(h(v1) != h(v1_other));
+ assert(h(v2) == h(v2));
+ assert(h(v2) != h(v2_other));
+ assert(h(v3) == h(v3));
+ assert(h(v3) != h(v3_other));
+ assert(h(v0) != h(v1));
+ assert(h(v0) != h(v2));
+ assert(h(v0) != h(v3));
+ assert(h(v1) != h(v2));
+ assert(h(v1) != h(v3));
+ assert(h(v2) != h(v3));
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ using V = std::variant<int, MakeEmptyT>;
+ using H = std::hash<V>;
+ V v;
+ makeEmpty(v);
+ V v2;
+ makeEmpty(v2);
+ const H h{};
+ assert(h(v) == h(v2));
+ }
+#endif
+}
+
+void test_hash_monostate() {
+ using H = std::hash<std::monostate>;
+ const H h{};
+ std::monostate m1{};
+ const std::monostate m2{};
+ assert(h(m1) == h(m1));
+ assert(h(m2) == h(m2));
+ assert(h(m1) == h(m2));
+ {
+ ASSERT_SAME_TYPE(decltype(h(m1)), std::size_t);
+ static_assert(std::is_copy_constructible<H>::value, "");
+ }
+}
+
+void test_hash_variant_duplicate_elements() {
+ // Test that the index of the alternative participates in the hash value.
+ using V = std::variant<std::monostate, std::monostate>;
+ using H = std::hash<V>;
+ H h{};
+ const V v1(std::in_place_index<0>);
+ const V v2(std::in_place_index<1>);
+ assert(h(v1) == h(v1));
+ assert(h(v2) == h(v2));
+ LIBCPP_ASSERT(h(v1) != h(v2));
+}
+
+int main() {
+ test_hash_variant();
+ test_hash_variant_duplicate_elements();
+ test_hash_monostate();
+}