1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
13 // template <class... Types> struct hash<variant<Types...>>;
14 // template <> struct hash<monostate>;
17 #include <type_traits>
20 #include "test_macros.h"
21 #include "variant_test_helpers.h"
22 #include "poisoned_hash_helper.h"
24 #ifndef TEST_HAS_NO_EXCEPTIONS
26 template <> struct hash
<::MakeEmptyT
> {
27 std::size_t operator()(const ::MakeEmptyT
&) const {
35 void test_hash_variant() {
37 using V
= std::variant
<int, long, int>;
38 using H
= std::hash
<V
>;
39 const V
v(std::in_place_index
<0>, 42);
41 V
v2(std::in_place_index
<0>, 100);
44 assert(h(v
) != h(v2
));
45 assert(h(v
) == h(v_copy
));
47 ASSERT_SAME_TYPE(decltype(h(v
)), std::size_t);
48 static_assert(std::is_copy_constructible
<H
>::value
, "");
52 using V
= std::variant
<std::monostate
, int, long, const char *>;
53 using H
= std::hash
<V
>;
54 const char *str
= "hello";
58 const V
v1_other(100);
62 V
v3_other("not hello");
64 assert(h(v0
) == h(v0
));
65 assert(h(v0
) == h(v0_other
));
66 assert(h(v1
) == h(v1
));
67 assert(h(v1
) != h(v1_other
));
68 assert(h(v2
) == h(v2
));
69 assert(h(v2
) != h(v2_other
));
70 assert(h(v3
) == h(v3
));
71 assert(h(v3
) != h(v3_other
));
72 assert(h(v0
) != h(v1
));
73 assert(h(v0
) != h(v2
));
74 assert(h(v0
) != h(v3
));
75 assert(h(v1
) != h(v2
));
76 assert(h(v1
) != h(v3
));
77 assert(h(v2
) != h(v3
));
79 #ifndef TEST_HAS_NO_EXCEPTIONS
81 using V
= std::variant
<int, MakeEmptyT
>;
82 using H
= std::hash
<V
>;
88 assert(h(v
) == h(v2
));
93 void test_hash_monostate() {
94 using H
= std::hash
<std::monostate
>;
97 const std::monostate m2
{};
98 assert(h(m1
) == h(m1
));
99 assert(h(m2
) == h(m2
));
100 assert(h(m1
) == h(m2
));
102 ASSERT_SAME_TYPE(decltype(h(m1
)), std::size_t);
103 ASSERT_NOEXCEPT(h(m1
));
104 static_assert(std::is_copy_constructible
<H
>::value
, "");
107 test_hash_enabled_for_type
<std::monostate
>();
111 void test_hash_variant_duplicate_elements() {
112 // Test that the index of the alternative participates in the hash value.
113 using V
= std::variant
<std::monostate
, std::monostate
>;
114 using H
= std::hash
<V
>;
116 const V
v1(std::in_place_index
<0>);
117 const V
v2(std::in_place_index
<1>);
118 assert(h(v1
) == h(v1
));
119 assert(h(v2
) == h(v2
));
120 LIBCPP_ASSERT(h(v1
) != h(v2
));
130 std::size_t operator()(B
const&) const {
137 void test_hash_variant_enabled() {
139 test_hash_enabled_for_type
<std::variant
<int> >();
140 test_hash_enabled_for_type
<std::variant
<int*, long, double, const int> >();
143 test_hash_disabled_for_type
<std::variant
<int, A
>>();
144 test_hash_disabled_for_type
<std::variant
<const A
, void*>>();
147 test_hash_enabled_for_type
<std::variant
<int, B
>>();
148 test_hash_enabled_for_type
<std::variant
<const B
, int>>();
152 int main(int, char**) {
154 test_hash_variant_duplicate_elements();
155 test_hash_monostate();
156 test_hash_variant_enabled();