|
|
@@ -11,16 +11,23 @@
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
-#include "copy_ptr.hpp"
|
|
|
+#include "value_ptr.hpp"
|
|
|
+
|
|
|
+struct copy_me {};
|
|
|
+struct copy_me_throw {};
|
|
|
+
|
|
|
+namespace detail {
|
|
|
+ template<> class value_ptr_copy<copy_me_throw> {
|
|
|
+ protected:
|
|
|
+ copy_me_throw * Copy(copy_me_throw const * p) const {
|
|
|
+ if (p == nullptr) { throw std::runtime_error{"NULL"}; }
|
|
|
+ return new copy_me_throw{*p};
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|
|
|
|
|
|
class copy_ptr_TestSuite : public CxxTest::TestSuite {
|
|
|
private:
|
|
|
- struct copy_me {};
|
|
|
-
|
|
|
- static copy_me * throw_clone(copy_me const * p) {
|
|
|
- if (p == nullptr) { throw std::runtime_error{"NULL"}; }
|
|
|
- return new copy_me{*p};
|
|
|
- }
|
|
|
|
|
|
class base {
|
|
|
public:
|
|
|
@@ -44,27 +51,27 @@ private:
|
|
|
};
|
|
|
public:
|
|
|
void test_copy_new_obj() {
|
|
|
- copy_ptr<copy_me> c1 { new copy_me };
|
|
|
- copy_ptr<copy_me> c2 { c1 };
|
|
|
+ value_ptr<copy_me> c1 { new copy_me };
|
|
|
+ value_ptr<copy_me> c2 { c1 };
|
|
|
TS_ASSERT_DIFFERS( c1.get(), c2.get() );
|
|
|
}
|
|
|
|
|
|
void test_copy_with_nullptr() {
|
|
|
- copy_ptr<copy_me> c1 { nullptr };
|
|
|
- copy_ptr<copy_me> c2 { c1 };
|
|
|
+ value_ptr<copy_me> c1 { nullptr };
|
|
|
+ value_ptr<copy_me> c2 { c1 };
|
|
|
TS_ASSERT_EQUALS( c1.get(), nullptr );
|
|
|
TS_ASSERT_EQUALS( c1.get(), c2.get() );
|
|
|
}
|
|
|
|
|
|
void test_copy_custom_func() {
|
|
|
- using ptr_t = copy_ptr<copy_me, ©_ptr_TestSuite::throw_clone>;
|
|
|
- ptr_t c1 { new copy_me };
|
|
|
+ using ptr_t = value_ptr<copy_me_throw>;
|
|
|
+ ptr_t c1 { new copy_me_throw };
|
|
|
ptr_t c2 { c1 };
|
|
|
TS_ASSERT_DIFFERS( c1.get(), c2.get() );
|
|
|
}
|
|
|
|
|
|
void test_copy_custom_func_with_nullptr() {
|
|
|
- using ptr_t = copy_ptr<copy_me, ©_ptr_TestSuite::throw_clone>;
|
|
|
+ using ptr_t = value_ptr<copy_me_throw>;
|
|
|
ptr_t c1 { nullptr };
|
|
|
TS_ASSERT_THROWS( ptr_t{ c1 }, std::runtime_error );
|
|
|
}
|
|
|
@@ -72,14 +79,14 @@ public:
|
|
|
void test_copy_object_is_deep_equals() {
|
|
|
using vec_t = std::vector<int>;
|
|
|
vec_t my_vec = { 1, 3, 5, 3, 6, 1, 2, -1, 0 };
|
|
|
- copy_ptr<vec_t> c1{ new vec_t{ my_vec } };
|
|
|
+ value_ptr<vec_t> c1{ new vec_t{ my_vec } };
|
|
|
TS_ASSERT_EQUALS( *c1, my_vec );
|
|
|
- copy_ptr<vec_t> c2{ c1 };
|
|
|
+ value_ptr<vec_t> c2{ c1 };
|
|
|
TS_ASSERT_EQUALS( *c2, *c1 );
|
|
|
}
|
|
|
|
|
|
void test_clone_polymorpic_object() {
|
|
|
- using ptr_t = clone_ptr<base, &base::clone>;
|
|
|
+ using ptr_t = value_ptr<base>;
|
|
|
ptr_t c0 { new derived_0 };
|
|
|
TS_ASSERT_EQUALS( ptr_t( c0 )->id(), derived_0::ID);
|
|
|
ptr_t c1 { new derived_1 };
|
|
|
@@ -87,7 +94,7 @@ public:
|
|
|
}
|
|
|
|
|
|
void test_clone_polymorphic_with_nullptr() {
|
|
|
- using ptr_t = clone_ptr<base, &base::clone>;
|
|
|
+ using ptr_t = value_ptr<base>;
|
|
|
ptr_t c1 { nullptr };
|
|
|
ptr_t c2 { c1 };
|
|
|
TS_ASSERT_EQUALS( c1.get(), nullptr );
|
|
|
@@ -101,7 +108,31 @@ public:
|
|
|
bool & _r;
|
|
|
};
|
|
|
test_t * test_struct = new test_t{has_delete};
|
|
|
- copy_ptr<test_t, nullptr>{ std::move(test_struct) };
|
|
|
+ TS_ASSERT_THROWS_NOTHING(value_ptr<test_t>{ std::move(test_struct) });
|
|
|
TS_ASSERT_EQUALS(has_delete, true);
|
|
|
}
|
|
|
+
|
|
|
+ void test_does_own_temporary() const {
|
|
|
+ bool has_delete{false};
|
|
|
+ struct test_t {
|
|
|
+ ~test_t() { _r = true; }
|
|
|
+ bool & _r;
|
|
|
+ };
|
|
|
+ TS_ASSERT_THROWS_NOTHING(value_ptr<test_t>{ new test_t{has_delete} });
|
|
|
+ TS_ASSERT_EQUALS(has_delete, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ void test_does_copy_on_copy() const {
|
|
|
+ int deleted{0};
|
|
|
+ struct test_t {
|
|
|
+ ~test_t() { ++(*_r); }
|
|
|
+ int * _r;
|
|
|
+ };
|
|
|
+ {
|
|
|
+ std::unique_ptr<test_t> test_struct{new test_t{&deleted}};
|
|
|
+ TS_ASSERT_THROWS_NOTHING(value_ptr<test_t>::copy_of( test_struct.get() ));
|
|
|
+ TS_ASSERT_EQUALS(deleted, 1);
|
|
|
+ }
|
|
|
+ TS_ASSERT_EQUALS(deleted, 2);
|
|
|
+ }
|
|
|
};
|