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> {
29   size_t operator()(B const&) { return 0; }
30 };
31 
32 }
33 
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         typedef int T;
42         optional<T> opt;
43         ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
44         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
45         opt = 2;
46         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
47     }
48     {
49         typedef std::string T;
50         optional<T> opt;
51         ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
52         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
53         opt = std::string("123");
54         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
55     }
56     {
57         typedef std::unique_ptr<int> T;
58         optional<T> opt;
59         ASSERT_NOT_NOEXCEPT(std::hash<optional<T>>()(opt));
60         assert(std::hash<optional<T>>{}(opt) == nullopt_hash);
61         opt = std::unique_ptr<int>(new int(3));
62         assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt));
63     }
64     {
65       test_hash_enabled_for_type<std::optional<int> >();
66       test_hash_enabled_for_type<std::optional<int*> >();
67       test_hash_enabled_for_type<std::optional<const int> >();
68       test_hash_enabled_for_type<std::optional<int* const> >();
69 
70       test_hash_disabled_for_type<std::optional<A>>();
71       test_hash_disabled_for_type<std::optional<const A>>();
72 
73       test_hash_enabled_for_type<std::optional<B>>();
74       test_hash_enabled_for_type<std::optional<const B>>();
75     }
76 }
77