xref: /llvm-project/libcxx/test/support/unique_ptr_test_helper.h (revision 30dadaa2eb499395f5bef44b9e1a18db6360ad1f)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
10 #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
11 
12 #include <memory>
13 #include <type_traits>
14 
15 #include "test_macros.h"
16 #include "deleter_types.h"
17 
18 struct A {
19   static int count;
AA20   TEST_CONSTEXPR_CXX23 A() {
21     if (!TEST_IS_CONSTANT_EVALUATED)
22       ++count;
23   }
AA24   TEST_CONSTEXPR_CXX23 A(const A&) {
25     if (!TEST_IS_CONSTANT_EVALUATED)
26       ++count;
27   }
~AA28   TEST_CONSTEXPR_CXX23 virtual ~A() {
29     if (!TEST_IS_CONSTANT_EVALUATED)
30       --count;
31   }
32 };
33 
34 int A::count = 0;
35 
36 struct B : public A {
37   static int count;
BB38   TEST_CONSTEXPR_CXX23 B() {
39     if (!TEST_IS_CONSTANT_EVALUATED)
40       ++count;
41   }
BB42   TEST_CONSTEXPR_CXX23 B(const B& other) : A(other) {
43     if (!TEST_IS_CONSTANT_EVALUATED)
44       ++count;
45   }
~BB46   TEST_CONSTEXPR_CXX23 virtual ~B() {
47     if (!TEST_IS_CONSTANT_EVALUATED)
48       --count;
49   }
50 };
51 
52 int B::count = 0;
53 
54 template <class T>
newValue(int num_elements)55 TEST_CONSTEXPR_CXX23 typename std::enable_if<!std::is_array<T>::value, T*>::type newValue(int num_elements) {
56   assert(num_elements == 1);
57   return new T;
58 }
59 
60 template <class T>
61 TEST_CONSTEXPR_CXX23 typename std::enable_if<std::is_array<T>::value, typename std::remove_all_extents<T>::type*>::type
newValue(int num_elements)62 newValue(int num_elements) {
63   typedef typename std::remove_all_extents<T>::type VT;
64   assert(num_elements >= 1);
65   return new VT[num_elements];
66 }
67 
68 struct IncompleteType;
69 
70 void checkNumIncompleteTypeAlive(int i);
71 int getNumIncompleteTypeAlive();
72 IncompleteType* getNewIncomplete();
73 IncompleteType* getNewIncompleteArray(int size);
74 
75 #if TEST_STD_VER >= 11
76 template <class ThisT, class... Args>
77 struct args_is_this_type : std::false_type {};
78 
79 template <class ThisT, class A1>
80 struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
81 #endif
82 
83 template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT> >
84 struct StoresIncomplete {
85   static_assert(
86       (std::is_same<IncompleteT, IncompleteType>::value || std::is_same<IncompleteT, IncompleteType[]>::value), "");
87 
88   std::unique_ptr<IncompleteT, Del> m_ptr;
89 
90 #if TEST_STD_VER >= 11
91   StoresIncomplete(StoresIncomplete const&) = delete;
92   StoresIncomplete(StoresIncomplete&&)      = default;
93 
94   template <class... Args>
95   StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
96     static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
97   }
98 #else
99 
100 private:
101   StoresIncomplete();
102   StoresIncomplete(StoresIncomplete const&);
103 
104 public:
105 #endif
106 
107   ~StoresIncomplete();
108 
109   IncompleteType* get() const { return m_ptr.get(); }
110   Del& get_deleter() { return m_ptr.get_deleter(); }
111 };
112 
113 #if TEST_STD_VER >= 11
114 template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT>, class... Args>
115 void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
116   checkNumIncompleteTypeAlive(expect_alive);
117   {
118     StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
119     checkNumIncompleteTypeAlive(expect_alive);
120     if (expect_alive == 0)
121       assert(sptr.get() == nullptr);
122     else
123       assert(sptr.get() != nullptr);
124   }
125   checkNumIncompleteTypeAlive(0);
126 }
127 #endif
128 
129 #define INCOMPLETE_TEST_EPILOGUE()                                                                                     \
130   int is_incomplete_test_anchor = is_incomplete_test();                                                                \
131                                                                                                                        \
132   struct IncompleteType {                                                                                              \
133     static int count;                                                                                                  \
134     IncompleteType() { ++count; }                                                                                      \
135     ~IncompleteType() { --count; }                                                                                     \
136   };                                                                                                                   \
137                                                                                                                        \
138   int IncompleteType::count = 0;                                                                                       \
139                                                                                                                        \
140   void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); }                                      \
141   int getNumIncompleteTypeAlive() { return IncompleteType::count; }                                                    \
142   IncompleteType* getNewIncomplete() { return new IncompleteType; }                                                    \
143   IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; }                                 \
144                                                                                                                        \
145   template <class IncompleteT, class Del>                                                                              \
146   StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
147 #
148 
149 #if TEST_STD_VER >= 11
150 #  define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                                                       \
151     static int is_incomplete_test() { __VA_ARGS__ return 0; }                                                          \
152     INCOMPLETE_TEST_EPILOGUE()
153 #else
154 #  define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                                                       \
155     static int is_incomplete_test() { return 0; }                                                                      \
156     INCOMPLETE_TEST_EPILOGUE()
157 #endif
158 
159 #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
160