diff options
author | Colin Snover | 2017-11-17 23:28:15 -0600 |
---|---|---|
committer | Eugene Sandulenko | 2017-11-18 22:35:12 +0100 |
commit | 076667dc0064432a3d4e3cf696d6688ee01a17a9 (patch) | |
tree | 1c2c622acc4a660109bf0a8ba22c94e8c4ee1c2c /test/common | |
parent | 62d6a80c869ee76eeb5abb99b29955399414f71a (diff) | |
download | scummvm-rg350-076667dc0064432a3d4e3cf696d6688ee01a17a9.tar.gz scummvm-rg350-076667dc0064432a3d4e3cf696d6688ee01a17a9.tar.bz2 scummvm-rg350-076667dc0064432a3d4e3cf696d6688ee01a17a9.zip |
COMMON: Add limited support for custom deleters to ScopedPtr
Custom deleters of ScopedPtr are not currently fully conforming to
C++11's support for custom deleters in std::unique_ptr for the
sake of simplicity of implementation. Unlike in the standard
library, plain functions and lvalue references are not supported,
nor may custom deleters be passed to the constructor at runtime.
This can be improved in the future, if necessary, by doing what
standard library implementations usually do and creating a Pair
class that uses the Empty Base Optimization idiom to avoid extra
storage overhead of the deleter instance when it is not needed, as
in typical standard library implementations, plus some additional
type traits to support the necessary metaprogramming for the
different type overloads.
Diffstat (limited to 'test/common')
-rw-r--r-- | test/common/ptr.h | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/test/common/ptr.h b/test/common/ptr.h index ebd978959a..0c871a761d 100644 --- a/test/common/ptr.h +++ b/test/common/ptr.h @@ -5,6 +5,14 @@ class PtrTestSuite : public CxxTest::TestSuite { public: + struct A { + int a; + }; + + struct B : public A { + int b; + }; + // A simple class which keeps track of all its instances class InstanceCountingClass { public: @@ -26,6 +34,61 @@ class PtrTestSuite : public CxxTest::TestSuite { TS_ASSERT_EQUALS(InstanceCountingClass::count, 0); } + struct CustomDeleter { + static bool invoked; + void operator()(int *object) { + invoked = true; + delete object; + } + }; + + void test_scoped_deleter() { + CustomDeleter::invoked = false; + + { + Common::ScopedPtr<int, CustomDeleter> a(new int(0)); + TS_ASSERT(!CustomDeleter::invoked); + } + + TS_ASSERT(CustomDeleter::invoked); + } + + void test_disposable_deleter() { + CustomDeleter::invoked = false; + + { + Common::DisposablePtr<int, CustomDeleter> a1(new int, DisposeAfterUse::YES); + TS_ASSERT(!CustomDeleter::invoked); + } + + TS_ASSERT(CustomDeleter::invoked); + CustomDeleter::invoked = false; + + int *a = new int; + { + Common::DisposablePtr<int, CustomDeleter> a2(a, DisposeAfterUse::NO); + } + + TS_ASSERT(!CustomDeleter::invoked); + delete a; + } + + void test_scoped_deref() { + A *raw = new A(); + raw->a = 123; + Common::ScopedPtr<A> a(raw); + TS_ASSERT_EQUALS(&*a, &*raw); + TS_ASSERT_EQUALS(a->a, raw->a); + } + + void test_disposable_deref() { + A *raw = new A(); + raw->a = 123; + Common::DisposablePtr<A> a(raw, DisposeAfterUse::YES); + TS_ASSERT_EQUALS(&*a, &*raw); + TS_ASSERT_EQUALS(a->a, raw->a); + } + void test_assign() { Common::SharedPtr<int> p1(new int(1)); TS_ASSERT(p1.unique()); @@ -88,14 +151,6 @@ class PtrTestSuite : public CxxTest::TestSuite { TS_ASSERT(!p1); } - struct A { - int a; - }; - - struct B : public A { - int b; - }; - void test_cast() { Common::SharedPtr<B> b(new B); Common::SharedPtr<A> a(b); @@ -104,3 +159,4 @@ class PtrTestSuite : public CxxTest::TestSuite { }; int PtrTestSuite::InstanceCountingClass::count = 0; +bool PtrTestSuite::CustomDeleter::invoked = false; |