forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			157 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
 | |
| #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
 | |
| 
 | |
| #include <memory>
 | |
| #include <type_traits>
 | |
| 
 | |
| #include "test_macros.h"
 | |
| #include "deleter_types.h"
 | |
| 
 | |
| struct A {
 | |
|   static int count;
 | |
|   A() { ++count; }
 | |
|   A(const A&) { ++count; }
 | |
|   virtual ~A() { --count; }
 | |
| };
 | |
| 
 | |
| int A::count = 0;
 | |
| 
 | |
| struct B : public A {
 | |
|   static int count;
 | |
|   B() { ++count; }
 | |
|   B(const B&) { ++count; }
 | |
|   virtual ~B() { --count; }
 | |
| };
 | |
| 
 | |
| int B::count = 0;
 | |
| 
 | |
| template <class T>
 | |
| typename std::enable_if<!std::is_array<T>::value, T*>::type
 | |
| newValue(int num_elements) {
 | |
|   assert(num_elements == 1);
 | |
|   return new T;
 | |
| }
 | |
| 
 | |
| template <class T>
 | |
| typename std::enable_if<std::is_array<T>::value,
 | |
|                         typename std::remove_all_extents<T>::type*>::type
 | |
| newValue(int num_elements) {
 | |
|   typedef typename std::remove_all_extents<T>::type VT;
 | |
|   assert(num_elements >= 1);
 | |
|   return new VT[num_elements];
 | |
| }
 | |
| 
 | |
| struct IncompleteType;
 | |
| 
 | |
| void checkNumIncompleteTypeAlive(int i);
 | |
| int getNumIncompleteTypeAlive();
 | |
| IncompleteType* getNewIncomplete();
 | |
| IncompleteType* getNewIncompleteArray(int size);
 | |
| 
 | |
| #if TEST_STD_VER >= 11
 | |
| template <class ThisT, class ...Args>
 | |
| struct args_is_this_type : std::false_type {};
 | |
| 
 | |
| template <class ThisT, class A1>
 | |
| struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
 | |
| #endif
 | |
| 
 | |
| template <class IncompleteT = IncompleteType,
 | |
|           class Del = std::default_delete<IncompleteT> >
 | |
| struct StoresIncomplete {
 | |
|   static_assert((std::is_same<IncompleteT, IncompleteType>::value ||
 | |
|                  std::is_same<IncompleteT, IncompleteType[]>::value), "");
 | |
| 
 | |
|   std::unique_ptr<IncompleteT, Del> m_ptr;
 | |
| 
 | |
| #if TEST_STD_VER >= 11
 | |
|   StoresIncomplete(StoresIncomplete const&) = delete;
 | |
|   StoresIncomplete(StoresIncomplete&&) = default;
 | |
| 
 | |
|   template <class ...Args>
 | |
|   StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
 | |
|     static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
 | |
|   }
 | |
| #else
 | |
| private:
 | |
|   StoresIncomplete();
 | |
|   StoresIncomplete(StoresIncomplete const&);
 | |
| public:
 | |
| #endif
 | |
| 
 | |
|   ~StoresIncomplete();
 | |
| 
 | |
|   IncompleteType* get() const { return m_ptr.get(); }
 | |
|   Del& get_deleter() { return m_ptr.get_deleter(); }
 | |
| };
 | |
| 
 | |
| #if TEST_STD_VER >= 11
 | |
| template <class IncompleteT = IncompleteType,
 | |
|           class Del = std::default_delete<IncompleteT>, class... Args>
 | |
| void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
 | |
|   checkNumIncompleteTypeAlive(expect_alive);
 | |
|   {
 | |
|     StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
 | |
|     checkNumIncompleteTypeAlive(expect_alive);
 | |
|     if (expect_alive == 0)
 | |
|       assert(sptr.get() == nullptr);
 | |
|     else
 | |
|       assert(sptr.get() != nullptr);
 | |
|   }
 | |
|   checkNumIncompleteTypeAlive(0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #define INCOMPLETE_TEST_EPILOGUE()                                             \
 | |
|   int is_incomplete_test_anchor = is_incomplete_test();                        \
 | |
|                                                                                \
 | |
|   struct IncompleteType {                                                      \
 | |
|     static int count;                                                          \
 | |
|     IncompleteType() { ++count; }                                              \
 | |
|     ~IncompleteType() { --count; }                                             \
 | |
|   };                                                                           \
 | |
|                                                                                \
 | |
|   int IncompleteType::count = 0;                                               \
 | |
|                                                                                \
 | |
|   void checkNumIncompleteTypeAlive(int i) {                                    \
 | |
|     assert(IncompleteType::count == i);                                        \
 | |
|   }                                                                            \
 | |
|   int getNumIncompleteTypeAlive() { return IncompleteType::count; }            \
 | |
|   IncompleteType* getNewIncomplete() { return new IncompleteType; }            \
 | |
|   IncompleteType* getNewIncompleteArray(int size) {                            \
 | |
|     return new IncompleteType[size];                                           \
 | |
|   }                                                                            \
 | |
|                                                                                \
 | |
|   template <class IncompleteT, class Del>                                      \
 | |
|   StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
 | |
| #
 | |
| 
 | |
| #if defined(__GNUC__)
 | |
| #pragma GCC diagnostic push
 | |
| #pragma GCC diagnostic ignored "-Wvariadic-macros"
 | |
| #endif
 | |
| 
 | |
| #if TEST_STD_VER >= 11
 | |
| #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
 | |
|   static int is_incomplete_test() { __VA_ARGS__ return 0; }                    \
 | |
|   INCOMPLETE_TEST_EPILOGUE()
 | |
| #else
 | |
| #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
 | |
|   static int is_incomplete_test() { return 0; }                                \
 | |
|   INCOMPLETE_TEST_EPILOGUE()
 | |
| #endif
 | |
| 
 | |
| #if defined(__GNUC__)
 | |
| #pragma GCC diagnostic pop
 | |
| #endif
 | |
| 
 | |
| #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
 |