//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H #include #include #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 typename std::enable_if::value, T*>::type newValue(int num_elements) { assert(num_elements == 1); return new T; } template typename std::enable_if::value, typename std::remove_all_extents::type*>::type newValue(int num_elements) { typedef typename std::remove_all_extents::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 struct args_is_this_type : std::false_type {}; template struct args_is_this_type : std::is_same::type> {}; #endif template > struct StoresIncomplete { static_assert((std::is_same::value || std::is_same::value), ""); std::unique_ptr m_ptr; #if TEST_STD_VER >= 11 StoresIncomplete(StoresIncomplete const&) = delete; StoresIncomplete(StoresIncomplete&&) = default; template StoresIncomplete(Args&&... args) : m_ptr(std::forward(args)...) { static_assert(!args_is_this_type::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... Args> void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) { checkNumIncompleteTypeAlive(expect_alive); { StoresIncomplete sptr(std::forward(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 \ StoresIncomplete::~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