123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- //===----------------------------------------------------------------------===//
- //
- // 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
|