160 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H10#define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H11 12#include <memory>13#include <type_traits>14 15#include "test_macros.h"16#include "deleter_types.h"17 18struct A {19 static int count;20 TEST_CONSTEXPR_CXX23 A() {21 if (!TEST_IS_CONSTANT_EVALUATED)22 ++count;23 }24 TEST_CONSTEXPR_CXX23 A(const A&) {25 if (!TEST_IS_CONSTANT_EVALUATED)26 ++count;27 }28 TEST_CONSTEXPR_CXX23 virtual ~A() {29 if (!TEST_IS_CONSTANT_EVALUATED)30 --count;31 }32};33 34int A::count = 0;35 36struct B : public A {37 static int count;38 TEST_CONSTEXPR_CXX23 B() {39 if (!TEST_IS_CONSTANT_EVALUATED)40 ++count;41 }42 TEST_CONSTEXPR_CXX23 B(const B& other) : A(other) {43 if (!TEST_IS_CONSTANT_EVALUATED)44 ++count;45 }46 TEST_CONSTEXPR_CXX23 virtual ~B() {47 if (!TEST_IS_CONSTANT_EVALUATED)48 --count;49 }50};51 52int B::count = 0;53 54template <class T>55TEST_CONSTEXPR_CXX23 typename std::enable_if<!std::is_array<T>::value, T*>::type newValue(int num_elements) {56 assert(num_elements == 1);57 return new T;58}59 60template <class T>61TEST_CONSTEXPR_CXX23 typename std::enable_if<std::is_array<T>::value, typename std::remove_all_extents<T>::type*>::type62newValue(int num_elements) {63 typedef typename std::remove_all_extents<T>::type VT;64 assert(num_elements >= 1);65 return new VT[num_elements];66}67 68struct IncompleteType;69 70void checkNumIncompleteTypeAlive(int i);71int getNumIncompleteTypeAlive();72IncompleteType* getNewIncomplete();73IncompleteType* getNewIncompleteArray(int size);74 75#if TEST_STD_VER >= 1176template <class ThisT, class... Args>77struct args_is_this_type : std::false_type {};78 79template <class ThisT, class A1>80struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};81#endif82 83template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT> >84struct StoresIncomplete {85 static_assert(86 (std::is_same<IncompleteT, IncompleteType>::value || std::is_same<IncompleteT, IncompleteType[]>::value), "");87 88 std::unique_ptr<IncompleteT, Del> m_ptr;89 90#if TEST_STD_VER >= 1191 StoresIncomplete(StoresIncomplete const&) = delete;92 StoresIncomplete(StoresIncomplete&&) = default;93 94 template <class... Args>95 StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {96 static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");97 }98#else99 100private:101 StoresIncomplete();102 StoresIncomplete(StoresIncomplete const&);103 104public:105#endif106 107 ~StoresIncomplete();108 109 IncompleteType* get() const { return m_ptr.get(); }110 Del& get_deleter() { return m_ptr.get_deleter(); }111};112 113#if TEST_STD_VER >= 11114template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT>, class... Args>115void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {116 checkNumIncompleteTypeAlive(expect_alive);117 {118 StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);119 checkNumIncompleteTypeAlive(expect_alive);120 if (expect_alive == 0)121 assert(sptr.get() == nullptr);122 else123 assert(sptr.get() != nullptr);124 }125 checkNumIncompleteTypeAlive(0);126}127#endif128 129#define INCOMPLETE_TEST_EPILOGUE() \130 int is_incomplete_test_anchor = is_incomplete_test(); \131 \132 struct IncompleteType { \133 static int count; \134 IncompleteType() { ++count; } \135 ~IncompleteType() { --count; } \136 }; \137 \138 int IncompleteType::count = 0; \139 \140 void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); } \141 int getNumIncompleteTypeAlive() { return IncompleteType::count; } \142 IncompleteType* getNewIncomplete() { return new IncompleteType; } \143 IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; } \144 \145 template <class IncompleteT, class Del> \146 StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}147#148 149#if TEST_STD_VER >= 11150# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \151 static int is_incomplete_test() { __VA_ARGS__ return 0; } \152 INCOMPLETE_TEST_EPILOGUE()153#else154# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \155 static int is_incomplete_test() { return 0; } \156 INCOMPLETE_TEST_EPILOGUE()157#endif158 159#endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H160