xref: /llvm-project/libcxx/test/support/unique_ptr_test_helper.h (revision 2561885f574ce7aedee4d30f3dbc6bfb09d64c06)
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