Home | History | Annotate | Download | only in support
      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
     11 #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
     12 
     13 #include <memory>
     14 #include <type_traits>
     15 
     16 #include "test_macros.h"
     17 #include "deleter_types.h"
     18 
     19 struct A {
     20   static int count;
     21   A() { ++count; }
     22   A(const A&) { ++count; }
     23   virtual ~A() { --count; }
     24 };
     25 
     26 int A::count = 0;
     27 
     28 struct B : public A {
     29   static int count;
     30   B() { ++count; }
     31   B(const B&) { ++count; }
     32   virtual ~B() { --count; }
     33 };
     34 
     35 int B::count = 0;
     36 
     37 template <class T>
     38 typename std::enable_if<!std::is_array<T>::value, T*>::type
     39 newValue(int num_elements) {
     40   assert(num_elements == 1);
     41   return new T;
     42 }
     43 
     44 template <class T>
     45 typename std::enable_if<std::is_array<T>::value,
     46                         typename std::remove_all_extents<T>::type*>::type
     47 newValue(int num_elements) {
     48   typedef typename std::remove_all_extents<T>::type VT;
     49   assert(num_elements >= 1);
     50   return new VT[num_elements];
     51 }
     52 
     53 struct IncompleteType;
     54 
     55 void checkNumIncompleteTypeAlive(int i);
     56 int getNumIncompleteTypeAlive();
     57 IncompleteType* getNewIncomplete();
     58 IncompleteType* getNewIncompleteArray(int size);
     59 
     60 #if TEST_STD_VER >= 11
     61 template <class ThisT, class ...Args>
     62 struct args_is_this_type : std::false_type {};
     63 
     64 template <class ThisT, class A1>
     65 struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
     66 #endif
     67 
     68 template <class IncompleteT = IncompleteType,
     69           class Del = std::default_delete<IncompleteT> >
     70 struct StoresIncomplete {
     71   static_assert((std::is_same<IncompleteT, IncompleteType>::value ||
     72                  std::is_same<IncompleteT, IncompleteType[]>::value), "");
     73 
     74   std::unique_ptr<IncompleteT, Del> m_ptr;
     75 
     76 #if TEST_STD_VER >= 11
     77   StoresIncomplete(StoresIncomplete const&) = delete;
     78   StoresIncomplete(StoresIncomplete&&) = default;
     79 
     80   template <class ...Args>
     81   StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
     82     static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
     83   }
     84 #else
     85 private:
     86   StoresIncomplete();
     87   StoresIncomplete(StoresIncomplete const&);
     88 public:
     89 #endif
     90 
     91   ~StoresIncomplete();
     92 
     93   IncompleteType* get() const { return m_ptr.get(); }
     94   Del& get_deleter() { return m_ptr.get_deleter(); }
     95 };
     96 
     97 #if TEST_STD_VER >= 11
     98 template <class IncompleteT = IncompleteType,
     99           class Del = std::default_delete<IncompleteT>, class... Args>
    100 void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
    101   using ValueT = typename std::remove_all_extents<IncompleteT>::type;
    102   checkNumIncompleteTypeAlive(expect_alive);
    103   {
    104     StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
    105     checkNumIncompleteTypeAlive(expect_alive);
    106     if (expect_alive == 0)
    107       assert(sptr.get() == nullptr);
    108     else
    109       assert(sptr.get() != nullptr);
    110   }
    111   checkNumIncompleteTypeAlive(0);
    112 }
    113 #endif
    114 
    115 #define INCOMPLETE_TEST_EPILOGUE()                                             \
    116   int is_incomplete_test_anchor = is_incomplete_test();                        \
    117                                                                                \
    118   struct IncompleteType {                                                      \
    119     static int count;                                                          \
    120     IncompleteType() { ++count; }                                              \
    121     ~IncompleteType() { --count; }                                             \
    122   };                                                                           \
    123                                                                                \
    124   int IncompleteType::count = 0;                                               \
    125                                                                                \
    126   void checkNumIncompleteTypeAlive(int i) {                                    \
    127     assert(IncompleteType::count == i);                                        \
    128   }                                                                            \
    129   int getNumIncompleteTypeAlive() { return IncompleteType::count; }            \
    130   IncompleteType* getNewIncomplete() { return new IncompleteType; }            \
    131   IncompleteType* getNewIncompleteArray(int size) {                            \
    132     return new IncompleteType[size];                                           \
    133   }                                                                            \
    134                                                                                \
    135   template <class IncompleteT, class Del>                                      \
    136   StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
    137 #
    138 
    139 #if defined(__GNUC__)
    140 #pragma GCC diagnostic push
    141 #pragma GCC diagnostic ignored "-Wvariadic-macros"
    142 #endif
    143 
    144 #if TEST_STD_VER >= 11
    145 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
    146   static int is_incomplete_test() { __VA_ARGS__ return 0; }                    \
    147   INCOMPLETE_TEST_EPILOGUE()
    148 #else
    149 #define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...)                                 \
    150   static int is_incomplete_test() { return 0; }                                \
    151   INCOMPLETE_TEST_EPILOGUE()
    152 #endif
    153 
    154 #if defined(__GNUC__)
    155 #pragma GCC diagnostic pop
    156 #endif
    157 
    158 #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
    159