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 #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H 11 #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H 12 13 #include <memory> 14 #include <type_traits> 15 16 #include "test_macros.h" 17 #include "deleter_types.h" 18 19 struct A { 20 static int count; 21 A() { ++count; } 22 A(const A&) { ++count; } 23 virtual ~A() { --count; } 24 }; 25 26 int A::count = 0; 27 28 struct B : public A { 29 static int count; 30 B() { ++count; } 31 B(const B&) { ++count; } 32 virtual ~B() { --count; } 33 }; 34 35 int B::count = 0; 36 37 template <class T> 38 typename std::enable_if<!std::is_array<T>::value, T*>::type 39 newValue(int num_elements) { 40 assert(num_elements == 1); 41 return new T; 42 } 43 44 template <class T> 45 typename std::enable_if<std::is_array<T>::value, 46 typename std::remove_all_extents<T>::type*>::type 47 newValue(int num_elements) { 48 typedef typename std::remove_all_extents<T>::type VT; 49 assert(num_elements >= 1); 50 return new VT[num_elements]; 51 } 52 53 struct IncompleteType; 54 55 void checkNumIncompleteTypeAlive(int i); 56 int getNumIncompleteTypeAlive(); 57 IncompleteType* getNewIncomplete(); 58 IncompleteType* getNewIncompleteArray(int size); 59 60 #if TEST_STD_VER >= 11 61 template <class ThisT, class ...Args> 62 struct args_is_this_type : std::false_type {}; 63 64 template <class ThisT, class A1> 65 struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {}; 66 #endif 67 68 template <class IncompleteT = IncompleteType, 69 class Del = std::default_delete<IncompleteT> > 70 struct StoresIncomplete { 71 static_assert((std::is_same<IncompleteT, IncompleteType>::value || 72 std::is_same<IncompleteT, IncompleteType[]>::value), ""); 73 74 std::unique_ptr<IncompleteT, Del> m_ptr; 75 76 #if TEST_STD_VER >= 11 77 StoresIncomplete(StoresIncomplete const&) = delete; 78 StoresIncomplete(StoresIncomplete&&) = default; 79 80 template <class ...Args> 81 StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) { 82 static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, ""); 83 } 84 #else 85 private: 86 StoresIncomplete(); 87 StoresIncomplete(StoresIncomplete const&); 88 public: 89 #endif 90 91 ~StoresIncomplete(); 92 93 IncompleteType* get() const { return m_ptr.get(); } 94 Del& get_deleter() { return m_ptr.get_deleter(); } 95 }; 96 97 #if TEST_STD_VER >= 11 98 template <class IncompleteT = IncompleteType, 99 class Del = std::default_delete<IncompleteT>, class... Args> 100 void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) { 101 using ValueT = typename std::remove_all_extents<IncompleteT>::type; 102 103 104 if (expect_alive == 0) 105 checkNumIncompleteTypeAlive(0); 106 else 107 checkNumIncompleteTypeAlive(expect_alive); 108 109 { 110 StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...); 111 checkNumIncompleteTypeAlive(expect_alive); 112 if (expect_alive == 0) 113 assert(sptr.get() == nullptr); 114 else 115 assert(sptr.get() != nullptr); 116 } 117 checkNumIncompleteTypeAlive(0); 118 } 119 #endif 120 121 #define INCOMPLETE_TEST_EPILOGUE() \ 122 int is_incomplete_test_anchor = is_incomplete_test(); \ 123 \ 124 struct IncompleteType { \ 125 static int count; \ 126 IncompleteType() { ++count; } \ 127 ~IncompleteType() { --count; } \ 128 }; \ 129 \ 130 int IncompleteType::count = 0; \ 131 \ 132 void checkNumIncompleteTypeAlive(int i) { \ 133 assert(IncompleteType::count == i); \ 134 } \ 135 int getNumIncompleteTypeAlive() { return IncompleteType::count; } \ 136 IncompleteType* getNewIncomplete() { return new IncompleteType; } \ 137 IncompleteType* getNewIncompleteArray(int size) { \ 138 return new IncompleteType[size]; \ 139 } \ 140 \ 141 template <class IncompleteT, class Del> \ 142 StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {} 143 # 144 145 #if defined(__GNUC__) 146 #pragma GCC diagnostic push 147 #pragma GCC diagnostic ignored "-Wvariadic-macros" 148 #endif 149 150 #if TEST_STD_VER >= 11 151 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ 152 static int is_incomplete_test() { __VA_ARGS__ return 0; } \ 153 INCOMPLETE_TEST_EPILOGUE() 154 #else 155 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ 156 static int is_incomplete_test() { return 0; } \ 157 INCOMPLETE_TEST_EPILOGUE() 158 #endif 159 160 #if defined(__GNUC__) 161 #pragma GCC diagnostic pop 162 #endif 163 164 #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H 165