12561885fSEric Fiselier //===----------------------------------------------------------------------===//
22561885fSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62561885fSEric Fiselier //
72561885fSEric Fiselier //===----------------------------------------------------------------------===//
82561885fSEric Fiselier
92561885fSEric Fiselier #ifndef TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
102561885fSEric Fiselier #define TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
112561885fSEric Fiselier
122561885fSEric Fiselier #include <memory>
132561885fSEric Fiselier #include <type_traits>
142561885fSEric Fiselier
152561885fSEric Fiselier #include "test_macros.h"
162561885fSEric Fiselier #include "deleter_types.h"
172561885fSEric Fiselier
182561885fSEric Fiselier struct A {
192561885fSEric Fiselier static int count;
AA20*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 A() {
21*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
22*30dadaa2SIgor Zhukov ++count;
23*30dadaa2SIgor Zhukov }
AA24*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 A(const A&) {
25*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
26*30dadaa2SIgor Zhukov ++count;
27*30dadaa2SIgor Zhukov }
~AA28*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 virtual ~A() {
29*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
30*30dadaa2SIgor Zhukov --count;
31*30dadaa2SIgor Zhukov }
322561885fSEric Fiselier };
332561885fSEric Fiselier
342561885fSEric Fiselier int A::count = 0;
352561885fSEric Fiselier
362561885fSEric Fiselier struct B : public A {
372561885fSEric Fiselier static int count;
BB38*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 B() {
39*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
40*30dadaa2SIgor Zhukov ++count;
41*30dadaa2SIgor Zhukov }
BB42*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 B(const B& other) : A(other) {
43*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
44*30dadaa2SIgor Zhukov ++count;
45*30dadaa2SIgor Zhukov }
~BB46*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 virtual ~B() {
47*30dadaa2SIgor Zhukov if (!TEST_IS_CONSTANT_EVALUATED)
48*30dadaa2SIgor Zhukov --count;
49*30dadaa2SIgor Zhukov }
502561885fSEric Fiselier };
512561885fSEric Fiselier
522561885fSEric Fiselier int B::count = 0;
532561885fSEric Fiselier
542561885fSEric Fiselier template <class T>
newValue(int num_elements)55*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 typename std::enable_if<!std::is_array<T>::value, T*>::type newValue(int num_elements) {
562561885fSEric Fiselier assert(num_elements == 1);
572561885fSEric Fiselier return new T;
582561885fSEric Fiselier }
592561885fSEric Fiselier
602561885fSEric Fiselier template <class T>
61*30dadaa2SIgor Zhukov TEST_CONSTEXPR_CXX23 typename std::enable_if<std::is_array<T>::value, typename std::remove_all_extents<T>::type*>::type
newValue(int num_elements)622561885fSEric Fiselier newValue(int num_elements) {
632561885fSEric Fiselier typedef typename std::remove_all_extents<T>::type VT;
642561885fSEric Fiselier assert(num_elements >= 1);
652561885fSEric Fiselier return new VT[num_elements];
662561885fSEric Fiselier }
672561885fSEric Fiselier
682561885fSEric Fiselier struct IncompleteType;
692561885fSEric Fiselier
702561885fSEric Fiselier void checkNumIncompleteTypeAlive(int i);
712561885fSEric Fiselier int getNumIncompleteTypeAlive();
722561885fSEric Fiselier IncompleteType* getNewIncomplete();
732561885fSEric Fiselier IncompleteType* getNewIncompleteArray(int size);
742561885fSEric Fiselier
752561885fSEric Fiselier #if TEST_STD_VER >= 11
762561885fSEric Fiselier template <class ThisT, class... Args>
772561885fSEric Fiselier struct args_is_this_type : std::false_type {};
782561885fSEric Fiselier
792561885fSEric Fiselier template <class ThisT, class A1>
802561885fSEric Fiselier struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {};
812561885fSEric Fiselier #endif
822561885fSEric Fiselier
83*30dadaa2SIgor Zhukov template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT> >
842561885fSEric Fiselier struct StoresIncomplete {
85*30dadaa2SIgor Zhukov static_assert(
86*30dadaa2SIgor Zhukov (std::is_same<IncompleteT, IncompleteType>::value || std::is_same<IncompleteT, IncompleteType[]>::value), "");
872561885fSEric Fiselier
882561885fSEric Fiselier std::unique_ptr<IncompleteT, Del> m_ptr;
892561885fSEric Fiselier
902561885fSEric Fiselier #if TEST_STD_VER >= 11
912561885fSEric Fiselier StoresIncomplete(StoresIncomplete const&) = delete;
922561885fSEric Fiselier StoresIncomplete(StoresIncomplete&&) = default;
932561885fSEric Fiselier
942561885fSEric Fiselier template <class... Args>
952561885fSEric Fiselier StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) {
962561885fSEric Fiselier static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, "");
972561885fSEric Fiselier }
982561885fSEric Fiselier #else
99*30dadaa2SIgor Zhukov
1002561885fSEric Fiselier private:
1012561885fSEric Fiselier StoresIncomplete();
1022561885fSEric Fiselier StoresIncomplete(StoresIncomplete const&);
103*30dadaa2SIgor Zhukov
1042561885fSEric Fiselier public:
1052561885fSEric Fiselier #endif
1062561885fSEric Fiselier
1072561885fSEric Fiselier ~StoresIncomplete();
1082561885fSEric Fiselier
1092561885fSEric Fiselier IncompleteType* get() const { return m_ptr.get(); }
1102561885fSEric Fiselier Del& get_deleter() { return m_ptr.get_deleter(); }
1112561885fSEric Fiselier };
1122561885fSEric Fiselier
1132561885fSEric Fiselier #if TEST_STD_VER >= 11
114*30dadaa2SIgor Zhukov template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT>, class... Args>
1152561885fSEric Fiselier void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
1162561885fSEric Fiselier checkNumIncompleteTypeAlive(expect_alive);
1172561885fSEric Fiselier {
1182561885fSEric Fiselier StoresIncomplete<IncompleteT, Del> sptr(std::forward<Args>(ctor_args)...);
1192561885fSEric Fiselier checkNumIncompleteTypeAlive(expect_alive);
1202561885fSEric Fiselier if (expect_alive == 0)
1212561885fSEric Fiselier assert(sptr.get() == nullptr);
1222561885fSEric Fiselier else
1232561885fSEric Fiselier assert(sptr.get() != nullptr);
1242561885fSEric Fiselier }
1252561885fSEric Fiselier checkNumIncompleteTypeAlive(0);
1262561885fSEric Fiselier }
1272561885fSEric Fiselier #endif
1282561885fSEric Fiselier
1292561885fSEric Fiselier #define INCOMPLETE_TEST_EPILOGUE() \
1302561885fSEric Fiselier int is_incomplete_test_anchor = is_incomplete_test(); \
1312561885fSEric Fiselier \
1322561885fSEric Fiselier struct IncompleteType { \
1332561885fSEric Fiselier static int count; \
1342561885fSEric Fiselier IncompleteType() { ++count; } \
1352561885fSEric Fiselier ~IncompleteType() { --count; } \
1362561885fSEric Fiselier }; \
1372561885fSEric Fiselier \
1382561885fSEric Fiselier int IncompleteType::count = 0; \
1392561885fSEric Fiselier \
140*30dadaa2SIgor Zhukov void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); } \
1412561885fSEric Fiselier int getNumIncompleteTypeAlive() { return IncompleteType::count; } \
1422561885fSEric Fiselier IncompleteType* getNewIncomplete() { return new IncompleteType; } \
143*30dadaa2SIgor Zhukov IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; } \
1442561885fSEric Fiselier \
1452561885fSEric Fiselier template <class IncompleteT, class Del> \
1462561885fSEric Fiselier StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {}
1472561885fSEric Fiselier #
1482561885fSEric Fiselier
1492561885fSEric Fiselier #if TEST_STD_VER >= 11
1502561885fSEric Fiselier # define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
1512561885fSEric Fiselier static int is_incomplete_test() { __VA_ARGS__ return 0; } \
1522561885fSEric Fiselier INCOMPLETE_TEST_EPILOGUE()
1532561885fSEric Fiselier #else
1542561885fSEric Fiselier # define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \
1552561885fSEric Fiselier static int is_incomplete_test() { return 0; } \
1562561885fSEric Fiselier INCOMPLETE_TEST_EPILOGUE()
1572561885fSEric Fiselier #endif
1582561885fSEric Fiselier
1592561885fSEric Fiselier #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H
160