// Copyright 2017 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include #include #include namespace { template struct PtrTraits; template struct PtrTraits> { using ObjType = typename fbl::remove_cv::type; static fbl::unique_ptr MakePointer(T* raw) { return fbl::unique_ptr(raw); } }; template struct PtrTraits> { using ObjType = typename fbl::remove_cv::type; static fbl::RefPtr MakePointer(T* raw) { return fbl::AdoptRef(raw); } }; class TestBase { public: TestBase() { recycle_was_called_ = false; } static bool recycle_was_called() { return recycle_was_called_; } protected: static bool recycle_was_called_; }; bool TestBase::recycle_was_called_; class TestPublicRecycle : public TestBase, public fbl::Recyclable { public: void fbl_recycle() { recycle_was_called_ = true; delete this; } }; class RefedTestPublicRecycle : public TestBase, public fbl::RefCounted, public fbl::Recyclable { public: void fbl_recycle() { recycle_was_called_ = true; delete this; } }; class TestPrivateRecycle : public TestBase, public fbl::Recyclable { private: friend class fbl::Recyclable; void fbl_recycle() { recycle_was_called_ = true; delete this; } }; class RefedTestPrivateRecycle : public TestBase, public fbl::RefCounted, public fbl::Recyclable { private: friend class fbl::Recyclable; void fbl_recycle() { recycle_was_called_ = true; delete this; } }; struct FailNoMethod : public fbl::Recyclable { }; struct FailBadRet : public fbl::Recyclable { int fbl_recycle() { return 1; } }; struct FailBadArg : public fbl::Recyclable { void fbl_recycle(int a = 1) {} }; class FailNotVis : public fbl::Recyclable { void fbl_recycle() {} }; #if TEST_WILL_NOT_COMPILE || 0 struct FailCVBase1 : public fbl::Recyclable { void fbl_recycle() {} }; #endif #if TEST_WILL_NOT_COMPILE || 0 struct FailCVBase2 : public fbl::Recyclable { void fbl_recycle() {} }; #endif #if TEST_WILL_NOT_COMPILE || 0 struct FailCVBase3 : public fbl::Recyclable { void fbl_recycle() {} }; #endif template static bool do_test() { BEGIN_TEST; fbl::AllocChecker ac; auto ptr = PtrTraits::MakePointer(new (&ac) typename PtrTraits::ObjType); ASSERT_TRUE(ac.check()); EXPECT_FALSE(TestBase::recycle_was_called()); ptr = nullptr; EXPECT_TRUE(TestBase::recycle_was_called()); END_TEST; } } // anon namespace BEGIN_TEST_CASE(fbl_recycle) RUN_NAMED_TEST("public unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("public const unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("public volatile unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("public const volatile unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("private unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("private const unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("private volatile unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("private const volatile unique_ptr fbl_recycle()", do_test>) RUN_NAMED_TEST("public RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("private RefPtr fbl_recycle()", do_test>) #if TEST_WILL_NOT_COMPILE || 0 // TODO(johngro) : If we ever support RefPtr<>s to const/volatile objects, // instantiate tests for them here. RUN_NAMED_TEST("public const RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("public volatile RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("public const volatile RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("private const RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("private volatile RefPtr fbl_recycle()", do_test>) RUN_NAMED_TEST("private const volatile RefPtr fbl_recycle()", do_test>) #endif #if TEST_WILL_NOT_COMPILE || 0 RUN_NAMED_TEST("FailNoMethod", do_test>); #endif #if TEST_WILL_NOT_COMPILE || 0 RUN_NAMED_TEST("FailBadRet", do_test>); #endif #if TEST_WILL_NOT_COMPILE || 0 RUN_NAMED_TEST("FailBadArg", do_test>); #endif #if TEST_WILL_NOT_COMPILE || 0 RUN_NAMED_TEST("FailNotVis", do_test>); #endif END_TEST_CASE(fbl_recycle);