1 | //===----------------------------------------------------------------------===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // <memory> |
10 | |
11 | // template <class T, class D> |
12 | // struct hash<unique_ptr<T, D>> |
13 | // { |
14 | // typedef unique_ptr<T, D> argument_type; |
15 | // typedef size_t result_type; |
16 | // size_t operator()(const unique_ptr<T, D>& p) const; |
17 | // }; |
18 | |
19 | #include <memory> |
20 | |
21 | #include <cassert> |
22 | #include <functional> |
23 | |
24 | #include "test_macros.h" |
25 | |
26 | #if TEST_STD_VER >= 11 |
27 | #include "poisoned_hash_helper.h" |
28 | #include "deleter_types.h" |
29 | #include "min_allocator.h" |
30 | |
31 | template <class ValueT, class Del> |
32 | void test_enabled_with_deleter() { |
33 | using UPtr = std::unique_ptr<ValueT, Del>; |
34 | using pointer = typename UPtr::pointer; |
35 | using RawDel = typename std::decay<Del>::type; |
36 | RawDel d(1); |
37 | UPtr p(nullptr, std::forward<Del>(d)); |
38 | test_hash_enabled_for_type<UPtr>(p); |
39 | test_hash_enabled_for_type<pointer>(); |
40 | } |
41 | |
42 | template <class ValueT, class Del> |
43 | void test_disabled_with_deleter() { |
44 | using UPtr = std::unique_ptr<ValueT, Del>; |
45 | using pointer = typename UPtr::pointer; |
46 | test_hash_disabled_for_type<UPtr>(); |
47 | test_hash_disabled_for_type<pointer>(); |
48 | } |
49 | |
50 | template <class T> |
51 | struct std::hash<min_pointer<T, std::integral_constant<std::size_t, 1>>> { |
52 | std::size_t operator()(min_pointer<T, std::integral_constant<size_t, 1>> p) const TEST_NOEXCEPT_FALSE { |
53 | if (!p) return 0; |
54 | return std::hash<T*>{}(std::addressof(*p)); |
55 | } |
56 | }; |
57 | |
58 | struct A {}; |
59 | |
60 | #endif // TEST_STD_VER >= 11 |
61 | |
62 | int main(int, char**) |
63 | { |
64 | { |
65 | int* ptr = new int; |
66 | std::unique_ptr<int> p(ptr); |
67 | std::hash<std::unique_ptr<int> > f; |
68 | std::size_t h = f(p); |
69 | assert(h == std::hash<int*>()(ptr)); |
70 | } |
71 | #if TEST_STD_VER >= 11 |
72 | { |
73 | std::unique_ptr<int, PointerDeleter<int, 1>> pThrowingHash; |
74 | std::hash<std::unique_ptr<int, PointerDeleter<int, 1>>> fThrowingHash; |
75 | ASSERT_NOT_NOEXCEPT(fThrowingHash(pThrowingHash)); |
76 | } |
77 | { |
78 | test_enabled_with_deleter<int, Deleter<int>>(); |
79 | test_enabled_with_deleter<int[], Deleter<int[]>>(); |
80 | test_enabled_with_deleter<int, CopyDeleter<int>>(); |
81 | test_enabled_with_deleter<int, CopyDeleter<int[]>>(); |
82 | test_enabled_with_deleter<int, NCDeleter<int>&>(); |
83 | test_enabled_with_deleter<int[], NCDeleter<int[]>&>(); |
84 | test_enabled_with_deleter<int, NCConstDeleter<int> const&>(); |
85 | test_enabled_with_deleter<int[], NCConstDeleter<int[]> const&>(); |
86 | } |
87 | { |
88 | test_enabled_with_deleter<int, PointerDeleter<int, 1>>(); |
89 | test_enabled_with_deleter<int[], PointerDeleter<int[], 1>>(); |
90 | test_enabled_with_deleter<A, PointerDeleter<A, 1>>(); |
91 | test_enabled_with_deleter<A[], PointerDeleter<A[], 1>>(); |
92 | |
93 | #if TEST_STD_VER > 14 |
94 | test_disabled_with_deleter<int, PointerDeleter<int, 0>>(); |
95 | test_disabled_with_deleter<int[], PointerDeleter<int[], 0>>(); |
96 | test_disabled_with_deleter<A, PointerDeleter<A, 0>>(); |
97 | test_disabled_with_deleter<A[], PointerDeleter<A[], 0>>(); |
98 | #endif |
99 | } |
100 | #endif |
101 | |
102 | return 0; |
103 | } |
104 | |