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