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;
AA21 A() { ++count; }
AA22 A(const A&) { ++count; }
~AA23 virtual ~A() { --count; }
24 };
25
26 int A::count = 0;
27
28 struct B : public A {
29 static int count;
BB30 B() { ++count; }
BB31 B(const B&) { ++count; }
~BB32 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
newValue(int num_elements)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
newValue(int num_elements)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 checkNumIncompleteTypeAlive(expect_alive);
102 {
103 StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
104 checkNumIncompleteTypeAlive(expect_alive);
105 if (expect_alive == 0)
106 assert(sptr.get() == nullptr);
107 else
108 assert(sptr.get() != nullptr);
109 }
110 checkNumIncompleteTypeAlive(0);
111 }
112 #endif
113
114 #define INCOMPLETE_TEST_EPILOGUE() \
115 int is_incomplete_test_anchor = is_incomplete_test(); \
116 \
117 struct IncompleteType { \
118 static int count; \
119 IncompleteType() { ++count; } \
120 ~IncompleteType() { --count; } \
121 }; \
122 \
123 int IncompleteType::count = 0; \
124 \
125 void checkNumIncompleteTypeAlive(int i) { \
126 assert(IncompleteType::count == i); \
127 } \
128 int getNumIncompleteTypeAlive() { return IncompleteType::count; } \
129 IncompleteType* getNewIncomplete() { return new IncompleteType; } \
130 IncompleteType* getNewIncompleteArray(int size) { \
131 return new IncompleteType[size]; \
132 } \
133 \
134 template <class IncompleteT, class Del> \
135 StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
136 #
137
138 #if defined(__GNUC__)
139 #pragma GCC diagnostic push
140 #pragma GCC diagnostic ignored "-Wvariadic-macros"
141 #endif
142
143 #if TEST_STD_VER >= 11
144 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
145 static int is_incomplete_test() { __VA_ARGS__ return 0; } \
146 INCOMPLETE_TEST_EPILOGUE()
147 #else
148 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
149 static int is_incomplete_test() { return 0; } \
150 INCOMPLETE_TEST_EPILOGUE()
151 #endif
152
153 #if defined(__GNUC__)
154 #pragma GCC diagnostic pop
155 #endif
156
157 #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
158