copy_ptr.t.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // copy_ptr.t.h
  3. // pointers
  4. //
  5. // Created by Sam Jaffe on 1/5/17.
  6. //
  7. #pragma once
  8. #include <cxxtest/TestSuite.h>
  9. #include <stdexcept>
  10. #include "copy_ptr.hpp"
  11. class copy_ptr_TestSuite : public CxxTest::TestSuite {
  12. private:
  13. struct copy_me {};
  14. static copy_me * throw_clone(copy_me const * p) {
  15. if (p == nullptr) { throw std::runtime_error{"NULL"}; }
  16. return new copy_me{*p};
  17. }
  18. class base {
  19. public:
  20. virtual ~base() {}
  21. virtual base* clone() const = 0;
  22. virtual int id() const = 0;
  23. };
  24. class derived_0 : public base {
  25. public:
  26. static const constexpr int ID = 0;
  27. virtual base * clone() const override { return new derived_0; }
  28. virtual int id() const override { return ID; }
  29. };
  30. class derived_1 : public base {
  31. public:
  32. static const constexpr int ID = 1;
  33. virtual base * clone() const override { return new derived_1; }
  34. virtual int id() const override { return ID; }
  35. };
  36. public:
  37. void test_copy_new_obj() {
  38. copy_ptr<copy_me> c1 { new copy_me };
  39. copy_ptr<copy_me> c2 { c1 };
  40. TS_ASSERT_DIFFERS( c1.get(), c2.get() );
  41. }
  42. void test_copy_with_nullptr() {
  43. copy_ptr<copy_me> c1 { nullptr };
  44. copy_ptr<copy_me> c2 { c1 };
  45. TS_ASSERT_EQUALS( c1.get(), nullptr );
  46. TS_ASSERT_EQUALS( c1.get(), c2.get() );
  47. }
  48. void test_copy_custom_func() {
  49. using ptr_t = copy_ptr<copy_me, &copy_ptr_TestSuite::throw_clone>;
  50. ptr_t c1 { new copy_me };
  51. ptr_t c2 { c1 };
  52. TS_ASSERT_DIFFERS( c1.get(), c2.get() );
  53. }
  54. void test_copy_custom_func_with_nullptr() {
  55. using ptr_t = copy_ptr<copy_me, &copy_ptr_TestSuite::throw_clone>;
  56. ptr_t c1 { nullptr };
  57. TS_ASSERT_THROWS( ptr_t{ c1 }, std::runtime_error );
  58. }
  59. void test_copy_object_is_deep_equals() {
  60. using vec_t = std::vector<int>;
  61. vec_t my_vec = { 1, 3, 5, 3, 6, 1, 2, -1, 0 };
  62. copy_ptr<vec_t> c1{ new vec_t{ my_vec } };
  63. TS_ASSERT_EQUALS( *c1, my_vec );
  64. copy_ptr<vec_t> c2{ c1 };
  65. TS_ASSERT_EQUALS( *c2, *c1 );
  66. }
  67. void test_clone_polymorpic_object() {
  68. using ptr_t = clone_ptr<base, &base::clone>;
  69. ptr_t c0 { new derived_0 };
  70. TS_ASSERT_EQUALS( ptr_t( c0 )->id(), derived_0::ID);
  71. ptr_t c1 { new derived_1 };
  72. TS_ASSERT_EQUALS( ptr_t( c1 )->id(), derived_1::ID);
  73. }
  74. void test_clone_polymorphic_with_nullptr() {
  75. using ptr_t = clone_ptr<base, &base::clone>;
  76. ptr_t c1 { nullptr };
  77. ptr_t c2 { c1 };
  78. TS_ASSERT_EQUALS( c1.get(), nullptr );
  79. TS_ASSERT_EQUALS( c1.get(), c2.get() );
  80. }
  81. void test_does_own() const {
  82. bool has_delete{false};
  83. struct test_t {
  84. ~test_t() { _r = true; }
  85. bool & _r;
  86. };
  87. test_t * test_struct = new test_t{has_delete};
  88. copy_ptr<test_t, nullptr>{ std::move(test_struct) };
  89. TS_ASSERT_EQUALS(has_delete, true);
  90. }
  91. };