1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 // <optional>
12 
13 // template <class T> struct hash<optional<T>>;
14 
15 #include <optional>
16 #include <string>
17 #include <memory>
18 #include <cassert>
19 
20 #include "poisoned_hash_helper.hpp"
21 
22 struct A {};
23 struct B {};
24 
25 namespace std {
26 
27 template <>
28 struct hash<B> {
operator ()std::hash29   size_t operator()(B const&) TEST_NOEXCEPT_FALSE { return 0; }
30 };
31 
32 }
33 
main()34 int main()
35 {
36     using std::optional;
37     const std::size_t nullopt_hash =
38         std::hash<optional<double>>{}(optional<double>{});
39 
40 
41     {
42         optional<B> opt;
43         ASSERT_NOT_NOEXCEPT(std::hash<optional<B>>()(opt));
44         ASSERT_NOT_NOEXCEPT(std::hash<optional<const B>>()(opt));
45     }
46 
47     {
48         typedef int T;
49         optional<T> opt;
50         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
51         opt = 2;
52         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
53     }
54     {
55         typedef std::string T;
56         optional<T> opt;
57         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
58         opt = std::string("123");
59         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
60     }
61     {
62         typedef std::unique_ptr<int> T;
63         optional<T> opt;
64         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
65         opt = std::unique_ptr<int>(new int(3));
66         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
67     }
68     {
69       test_hash_enabled_for_type<std::optional<int> >();
70       test_hash_enabled_for_type<std::optional<int*> >();
71       test_hash_enabled_for_type<std::optional<const int> >();
72       test_hash_enabled_for_type<std::optional<int* const> >();
73 
74       test_hash_disabled_for_type<std::optional<A>>();
75       test_hash_disabled_for_type<std::optional<const A>>();
76 
77       test_hash_enabled_for_type<std::optional<B>>();
78       test_hash_enabled_for_type<std::optional<const B>>();
79     }
80 }
81