ownership.C 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file ownership.C
  3. /// @brief Test ownership logic of array types.
  4. // (c) Daniel Llorens - 2014
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <iostream>
  10. #include <iterator>
  11. #include "ra/complex.H"
  12. #include "ra/test.H"
  13. #include "ra/big.H"
  14. #include "ra/operators.H"
  15. #include "ra/io.H"
  16. using std::cout, std::endl;
  17. using real = double;
  18. // TODO Test construction both by-value and by-ref, and between types.
  19. // TODO Correct and complete this table, both for
  20. // array-type-A::operator=(array-type-B) and for
  21. // array-type-A::array-type::A(array-type-B).
  22. // TODO Do/organize the tests for these tables.
  23. // The constructors are all plain, the fields of the array record are copied/moved.
  24. // TODO This table contain errors; review thoroughly.
  25. /*
  26. | to\fro cons | View | Shared | Unique | Big | Small | SmallView | Tested in |
  27. |-------------+----------------+--------+-----------+-----------+----------------+------------+------------------|
  28. | R | borrow | borrow | borrow | borrow | borrow | ... | |
  29. | Shared | share, null d. | share | move | share | share, null d. | | test/ownership.C |
  30. | Unique | copy | copy | move | copy/move | copy | | |
  31. | Big | copy | copy | copy/move | copy/move | copy | | |
  32. | Small | | | | | copy | | |
  33. */
  34. // operator= however copies into. This is so that array ops look natural.
  35. // The reason for the diagonal exceptions is to allow array-types to be initialized from a ref argument, which is required in operator>>(istream &, array-type). Maybe there's a better solution.
  36. /*
  37. | to\fro op= | View | Shared | Unique | Big | Small | Tested in |
  38. |------------+-----------+-----------+-----------+-------------+-----------+------------------|
  39. | View | copy into | copy into | copy into | copy into | copy into | test/operators.C |
  40. | Shared | copy into | *share* | copy into | copy into | copy into | |
  41. | Unique | copy into | copy into | *move* | copy into | copy into | |
  42. | Big | copy into | copy into | copy into | *copy/move* | copy into | |
  43. | Small | copy into | copy into | copy into | copy into | *copy* | |
  44. */
  45. // TODO Maybe I want Container/View<T> const and Container/View<T const> to behave differently....
  46. int main()
  47. {
  48. real const check99[5] = {99, 99, 99, 99, 99};
  49. real const check11[5] = {11, 11, 11, 11, 11};
  50. TestRecorder tr;
  51. tr.section("Unique");
  52. {
  53. ra::Unique<real, 1> o({5}, 11.);
  54. tr.test(o.store!=nullptr);
  55. // ra::Unique<real, 1> z(o); // TODO Check that it fails to compile
  56. ra::Unique<real, 1> z(std::move(o));
  57. tr.test(o.store==nullptr);
  58. tr.test(std::equal(check11, check11+5, z.begin())); // was moved
  59. ra::Unique<real, 1> const c(std::move(z));
  60. tr.test(z.store==nullptr);
  61. tr.test(std::equal(check11, check11+5, c.begin())); // was moved
  62. {
  63. ra::Unique<real, 1> o({5}, 11.);
  64. ra::Unique<real, 1> q {};
  65. q = std::move(o);
  66. tr.test(o.store==nullptr);
  67. tr.test(std::equal(check11, check11+5, q.begin())); // was moved
  68. }
  69. }
  70. tr.section("Big");
  71. {
  72. ra::Big<real, 1> o({5}, 11.);
  73. ra::Big<real, 1> z(o);
  74. o = 99.;
  75. tr.test(std::equal(check11, check11+5, z.begin()));
  76. tr.test(std::equal(check99, check99+5, o.begin()));
  77. tr.section("copy");
  78. {
  79. ra::Big<real, 1> const c(o);
  80. tr.test(std::equal(check99, check99+5, c.begin()));
  81. tr.test(c.data()!=o.data());
  82. ra::Big<real, 1> const q(c);
  83. tr.test(q.data()!=c.data());
  84. tr.test(std::equal(check99, check99+5, q.begin()));
  85. ra::Big<real, 1> p(c);
  86. tr.test(p.data()!=c.data());
  87. tr.test(std::equal(check99, check99+5, p.begin()));
  88. }
  89. tr.section("Container operator=(Container) replaces, unlike View [ra20]");
  90. {
  91. ra::Big<real, 1> o({5}, 11.);
  92. ra::Big<real, 1> const p({5}, 99.);
  93. {
  94. ra::Big<real, 1> q({7}, 4.);
  95. q = o;
  96. tr.test(std::equal(check11, check11+5, q.begin()));
  97. }
  98. {
  99. ra::Big<real, 1> q({7}, 4.);
  100. q = p;
  101. tr.test(std::equal(check99, check99+5, q.begin()));
  102. }
  103. {
  104. ra::Big<real, 1> q({7}, 4.);
  105. q = ra::Big<real, 1>({5}, 11.);
  106. tr.test(std::equal(check11, check11+5, q.begin()));
  107. }
  108. tr.test(std::equal(check99, check99+5, p.begin()));
  109. tr.test(std::equal(check11, check11+5, o.begin()));
  110. }
  111. tr.section("move");
  112. {
  113. ra::Big<real, 1> c(std::move(z));
  114. tr.test(z.store.size()==0); // std::vector does this on move...
  115. tr.test(std::equal(check11, check11+5, c.begin())); // was moved
  116. }
  117. }
  118. tr.section("Shared");
  119. {
  120. ra::Shared<real, 1> o({5}, 11.);
  121. ra::Shared<real, 1> z(o);
  122. o = 99.;
  123. tr.test(std::equal(check99, check99+5, z.begin()));
  124. ra::Shared<real, 1> const c(o);
  125. tr.test(std::equal(check99, check99+5, c.begin()));
  126. tr.test(c.data()==o.data());
  127. ra::Shared<real, 1> const q(c);
  128. tr.test(q.data()==c.data());
  129. ra::Shared<real, 1> p(c); // May be a BUG here; shared_ptr doesn't prevent this copy.
  130. tr.test(p.data()==c.data());
  131. }
  132. // The use of deleters allows Shared to work like View storage wise.
  133. tr.section("Shared with borrowed data");
  134. {
  135. ra::Shared<real, 1> o({5}, 11.);
  136. {
  137. ra::Shared<real, 1> borrower(ra::shared_borrowing(o));
  138. borrower = 99.;
  139. // Check that shared_borrowing really borrowed.
  140. tr.test(o.data()==borrower.data());
  141. }
  142. tr.test_eq(o, 99.);
  143. }
  144. return tr.summary();
  145. }