unique_ptr_test_helper.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
  9. #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
  10. #include <memory>
  11. #include <type_traits>
  12. #include "test_macros.h"
  13. #include "deleter_types.h"
  14. struct A {
  15. static int count;
  16. A() { ++count; }
  17. A(const A&) { ++count; }
  18. virtual ~A() { --count; }
  19. };
  20. int A::count = 0;
  21. struct B : public A {
  22. static int count;
  23. B() { ++count; }
  24. B(const B&) { ++count; }
  25. virtual ~B() { --count; }
  26. };
  27. int B::count = 0;
  28. template <class T>
  29. typename std::enable_if<!std::is_array<T>::value, T*>::type
  30. newValue(int num_elements) {
  31. assert(num_elements == 1);
  32. return new T;
  33. }
  34. template <class T>
  35. typename std::enable_if<std::is_array<T>::value,
  36. typename std::remove_all_extents<T>::type*>::type
  37. newValue(int num_elements) {
  38. typedef typename std::remove_all_extents<T>::type VT;
  39. assert(num_elements >= 1);
  40. return new VT[num_elements];
  41. }
  42. struct IncompleteType;
  43. void checkNumIncompleteTypeAlive(int i);
  44. int getNumIncompleteTypeAlive();
  45. IncompleteType* getNewIncomplete();
  46. IncompleteType* getNewIncompleteArray(int size);
  47. #if TEST_STD_VER >= 11
  48. template <class ThisT, class ...Args>
  49. struct args_is_this_type : std::false_type {};
  50. template <class ThisT, class A1>
  51. struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
  52. #endif
  53. template <class IncompleteT = IncompleteType,
  54. class Del = std::default_delete<IncompleteT> >
  55. struct StoresIncomplete {
  56. static_assert((std::is_same<IncompleteT, IncompleteType>::value ||
  57. std::is_same<IncompleteT, IncompleteType[]>::value), "");
  58. std::unique_ptr<IncompleteT, Del> m_ptr;
  59. #if TEST_STD_VER >= 11
  60. StoresIncomplete(StoresIncomplete const&) = delete;
  61. StoresIncomplete(StoresIncomplete&&) = default;
  62. template <class ...Args>
  63. StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
  64. static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
  65. }
  66. #else
  67. private:
  68. StoresIncomplete();
  69. StoresIncomplete(StoresIncomplete const&);
  70. public:
  71. #endif
  72. ~StoresIncomplete();
  73. IncompleteType* get() const { return m_ptr.get(); }
  74. Del& get_deleter() { return m_ptr.get_deleter(); }
  75. };
  76. #if TEST_STD_VER >= 11
  77. template <class IncompleteT = IncompleteType,
  78. class Del = std::default_delete<IncompleteT>, class... Args>
  79. void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
  80. checkNumIncompleteTypeAlive(expect_alive);
  81. {
  82. StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
  83. checkNumIncompleteTypeAlive(expect_alive);
  84. if (expect_alive == 0)
  85. assert(sptr.get() == nullptr);
  86. else
  87. assert(sptr.get() != nullptr);
  88. }
  89. checkNumIncompleteTypeAlive(0);
  90. }
  91. #endif
  92. #define INCOMPLETE_TEST_EPILOGUE() \
  93. int is_incomplete_test_anchor = is_incomplete_test(); \
  94. \
  95. struct IncompleteType { \
  96. static int count; \
  97. IncompleteType() { ++count; } \
  98. ~IncompleteType() { --count; } \
  99. }; \
  100. \
  101. int IncompleteType::count = 0; \
  102. \
  103. void checkNumIncompleteTypeAlive(int i) { \
  104. assert(IncompleteType::count == i); \
  105. } \
  106. int getNumIncompleteTypeAlive() { return IncompleteType::count; } \
  107. IncompleteType* getNewIncomplete() { return new IncompleteType; } \
  108. IncompleteType* getNewIncompleteArray(int size) { \
  109. return new IncompleteType[size]; \
  110. } \
  111. \
  112. template <class IncompleteT, class Del> \
  113. StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
  114. #
  115. #if defined(__GNUC__)
  116. #pragma GCC diagnostic push
  117. #pragma GCC diagnostic ignored "-Wvariadic-macros"
  118. #endif
  119. #if TEST_STD_VER >= 11
  120. #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
  121. static int is_incomplete_test() { __VA_ARGS__ return 0; } \
  122. INCOMPLETE_TEST_EPILOGUE()
  123. #else
  124. #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
  125. static int is_incomplete_test() { return 0; } \
  126. INCOMPLETE_TEST_EPILOGUE()
  127. #endif
  128. #if defined(__GNUC__)
  129. #pragma GCC diagnostic pop
  130. #endif
  131. #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H