| /* | |
| * Copyright 2022 Rive | |
| */ | |
| #include <rive/refcnt.hpp> | |
| #include <catch.hpp> | |
| #include <cstdio> | |
| using namespace rive; | |
| class MyRefCnt : public RefCnt<MyRefCnt> | |
| { | |
| public: | |
| MyRefCnt() {} | |
| MyRefCnt(int, float, bool) {} | |
| void require_count(int value) { REQUIRE(this->debugging_refcnt() == value); } | |
| }; | |
| TEST_CASE("refcnt", "[basics]") | |
| { | |
| MyRefCnt my; | |
| REQUIRE(my.debugging_refcnt() == 1); | |
| my.ref(); | |
| REQUIRE(my.debugging_refcnt() == 2); | |
| my.unref(); | |
| REQUIRE(my.debugging_refcnt() == 1); | |
| safe_ref(&my); | |
| REQUIRE(my.debugging_refcnt() == 2); | |
| safe_unref(&my); | |
| REQUIRE(my.debugging_refcnt() == 1); | |
| // just exercise these to be sure they don't crash | |
| safe_ref((MyRefCnt*)nullptr); | |
| safe_unref((MyRefCnt*)nullptr); | |
| } | |
| TEST_CASE("rcp", "[basics]") | |
| { | |
| rcp<MyRefCnt> r0(nullptr); | |
| REQUIRE(r0.get() == nullptr); | |
| REQUIRE(!r0); | |
| auto r1 = make_rcp<MyRefCnt>(); | |
| REQUIRE(r1.get() != nullptr); | |
| REQUIRE(r1); | |
| REQUIRE(r1 != r0); | |
| REQUIRE(r1->debugging_refcnt() == 1); | |
| auto r2 = r1; | |
| REQUIRE(r1.get() == r2.get()); | |
| REQUIRE(r1 == r2); | |
| REQUIRE(r2->debugging_refcnt() == 2); | |
| auto r3 = make_rcp<MyRefCnt>(1, .5f, false); | |
| REQUIRE(r3.get() != nullptr); | |
| REQUIRE(r3); | |
| REQUIRE(r3 != r1); | |
| REQUIRE(r3->debugging_refcnt() == 1); | |
| auto ptr = r2.release(); | |
| REQUIRE(r2.get() == nullptr); | |
| REQUIRE(r1.get() == ptr); | |
| // This is important, calling release() does not modify the ref count on the object | |
| // We have to manage that explicit since we called release() | |
| REQUIRE(r1->debugging_refcnt() == 2); | |
| ptr->unref(); | |
| REQUIRE(r1->debugging_refcnt() == 1); | |
| r1.reset(); | |
| REQUIRE(r1.get() == nullptr); | |
| struct A : public rive::RefCnt<A> | |
| { | |
| int x = 17; | |
| }; | |
| struct B : public A | |
| { | |
| int y = 21; | |
| }; | |
| auto b = make_rcp<B>(); | |
| CHECK(b->y == 21); | |
| rcp<A> a = b; | |
| CHECK(a->x == 17); | |
| CHECK(static_rcp_cast<B>(a)->y == 21); | |
| CHECK(rcp<A>(b)->x == 17); | |
| CHECK(a->debugging_refcnt() == 2); | |
| CHECK(b->debugging_refcnt() == 2); | |
| CHECK(static_rcp_cast<B>(std::move(a))->y == 21); | |
| CHECK(a == nullptr); | |
| CHECK(b->debugging_refcnt() == 1); | |
| a = ref_rcp(b.get()); | |
| CHECK(b == a); | |
| CHECK(a->debugging_refcnt() == 2); | |
| CHECK(a->x == 17); | |
| CHECK(static_rcp_cast<B>(a)->y == 21); | |
| } |