circular_buffer_test.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "catch.hpp"
  2. #include "circular_buffer.hh"
  3. #include <memory>
  4. #include <vector>
  5. using namespace std;
  6. static void check_buf(
  7. const circular_buffer<int>& buf,
  8. int expectedCapacity, const vector<int>& expectedElements)
  9. {
  10. int expectedSize = expectedElements.size();
  11. REQUIRE(buf.size() == expectedSize);
  12. CHECK(buf.capacity() == expectedCapacity);
  13. CHECK(buf.reserve() == expectedCapacity - expectedSize);
  14. CHECK(buf.empty() == (expectedSize == 0));
  15. CHECK(buf.full() == (expectedCapacity == expectedSize));
  16. if (expectedSize != 0) {
  17. CHECK(buf.front() == expectedElements.front());
  18. CHECK(buf.back() == expectedElements.back());
  19. }
  20. for (int i = 0; i < expectedSize; ++i) {
  21. CHECK(buf[i] == expectedElements[i]);
  22. }
  23. auto it1 = expectedElements.begin();
  24. for (auto& i : buf) {
  25. CHECK(i == *it1++);
  26. }
  27. auto rit = expectedElements.rbegin();
  28. for (auto it = buf.rbegin(); it != buf.rend(); ++it) {
  29. CHECK(*it == *rit++);
  30. }
  31. }
  32. TEST_CASE("circular_buffer") {
  33. circular_buffer<int> buf1; check_buf(buf1, 0, {});
  34. buf1.set_capacity(3); check_buf(buf1, 3, {});
  35. buf1.push_back(1); check_buf(buf1, 3, {1});
  36. buf1.push_back(2); check_buf(buf1, 3, {1,2});
  37. buf1.push_front(3); check_buf(buf1, 3, {3,1,2});
  38. buf1.pop_front(); check_buf(buf1, 3, {1,2});
  39. buf1.pop_back(); check_buf(buf1, 3, {1});
  40. buf1.clear(); check_buf(buf1, 3, {});
  41. circular_buffer<int> buf2(5); check_buf(buf2, 5, {});
  42. buf1.push_back({4,5}); check_buf(buf1, 3, {4,5});
  43. buf2.push_back({7,8,9}); check_buf(buf2, 5, {7,8,9});
  44. swap(buf1, buf2); check_buf(buf1, 5, {7,8,9});
  45. check_buf(buf2, 3, {4,5});
  46. }
  47. static void check_buf(
  48. const circular_buffer<unique_ptr<int>>& buf,
  49. int expectedCapacity, const vector<int>& expectedElements)
  50. {
  51. int expectedSize = expectedElements.size();
  52. REQUIRE(buf.size() == expectedSize);
  53. CHECK(buf.capacity() == expectedCapacity);
  54. CHECK(buf.reserve() == expectedCapacity - expectedSize);
  55. CHECK(buf.empty() == (expectedSize == 0));
  56. CHECK(buf.full() == (expectedCapacity == expectedSize));
  57. if (expectedSize != 0) {
  58. CHECK(*buf.front() == expectedElements.front());
  59. CHECK(*buf.back() == expectedElements.back());
  60. }
  61. for (int i = 0; i < expectedSize; ++i) {
  62. CHECK(*buf[i] == expectedElements[i]);
  63. }
  64. auto it1 = expectedElements.begin();
  65. for (auto& i : buf) {
  66. CHECK(*i == *it1++);
  67. }
  68. auto rit = expectedElements.rbegin();
  69. for (auto it = buf.rbegin(); it != buf.rend(); ++it) {
  70. CHECK(**it == *rit++);
  71. }
  72. }
  73. TEST_CASE("circular_buffer, move-only") {
  74. circular_buffer<unique_ptr<int>> buf1; check_buf(buf1, 0, {});
  75. buf1.set_capacity(3); check_buf(buf1, 3, {});
  76. buf1.push_back (make_unique<int>(1)); check_buf(buf1, 3, {1});
  77. buf1.push_back (make_unique<int>(2)); check_buf(buf1, 3, {1,2});
  78. buf1.push_front(make_unique<int>(3)); check_buf(buf1, 3, {3,1,2});
  79. buf1.pop_front(); check_buf(buf1, 3, {1,2});
  80. buf1.pop_back(); check_buf(buf1, 3, {1});
  81. buf1.clear(); check_buf(buf1, 3, {});
  82. // doesn't work, see
  83. // http://stackoverflow.com/questions/8193102/initializer-list-and-move-semantics
  84. //buf1.push_back({make_unique<int>(4),
  85. // make_unique<int>(5)}); check_buf(buf1, 3, {4,5});
  86. }
  87. static void check_queue(
  88. const cb_queue<int>& q, int expectedCapacity,
  89. const vector<int>& expectedElements)
  90. {
  91. check_buf(q.getBuffer(), expectedCapacity, expectedElements);
  92. }
  93. TEST_CASE("cb_queue") {
  94. cb_queue<int> q; check_queue(q, 0, {});
  95. q.push_back(1); check_queue(q, 4, {1});
  96. q.push_back(2); check_queue(q, 4, {1,2});
  97. CHECK(q.pop_front() == 1); check_queue(q, 4, {2});
  98. q.push_back({4,5,6,7}); check_queue(q, 8, {2,4,5,6,7});
  99. CHECK(q.pop_front() == 2); check_queue(q, 8, {4,5,6,7});
  100. CHECK(q.pop_front() == 4); check_queue(q, 8, {5,6,7});
  101. q.clear(); check_queue(q, 8, {});
  102. }
  103. static void check_queue(
  104. const cb_queue<unique_ptr<int>>& q, int expectedCapacity,
  105. const vector<int>& expectedElements)
  106. {
  107. check_buf(q.getBuffer(), expectedCapacity, expectedElements);
  108. }
  109. TEST_CASE("cb_queue, move-only") {
  110. cb_queue<unique_ptr<int>> q; check_queue(q, 0, {});
  111. q.push_back(make_unique<int>(1)); check_queue(q, 4, {1});
  112. q.push_back(make_unique<int>(2)); check_queue(q, 4, {1,2});
  113. CHECK(*q.pop_front() == 1); check_queue(q, 4, {2});
  114. q.clear(); check_queue(q, 4, {});
  115. }