test_bounded_queue.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright (c) 2006-2018 Maxim Khizhinsky
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H
  6. #define CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H
  7. #include <cds_test/check_size.h>
  8. namespace cds_test {
  9. class bounded_queue : public ::testing::Test
  10. {
  11. protected:
  12. template <typename Queue>
  13. void test( Queue& q )
  14. {
  15. typedef typename Queue::value_type value_type;
  16. value_type it;
  17. const size_t nSize = q.capacity();
  18. ASSERT_TRUE( q.empty());
  19. ASSERT_CONTAINER_SIZE( q, 0 );
  20. // enqueue/dequeue
  21. for ( unsigned pass = 0; pass < 3; ++pass ) {
  22. for ( size_t i = 0; i < nSize; ++i ) {
  23. it = static_cast<value_type>( i );
  24. ASSERT_TRUE( q.enqueue( it ));
  25. ASSERT_CONTAINER_SIZE( q, i + 1 );
  26. }
  27. ASSERT_FALSE( q.empty());
  28. ASSERT_CONTAINER_SIZE( q, nSize );
  29. ASSERT_FALSE( q.enqueue( static_cast<value_type>( nSize ) * 2 ));
  30. for ( size_t i = 0; i < nSize; ++i ) {
  31. it = -1;
  32. ASSERT_TRUE( q.dequeue( it ));
  33. ASSERT_EQ( it, static_cast<value_type>( i ));
  34. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  35. }
  36. ASSERT_TRUE( q.empty());
  37. ASSERT_CONTAINER_SIZE( q, 0 );
  38. }
  39. // push/pop
  40. for ( unsigned pass = 0; pass < 3; ++pass ) {
  41. for ( size_t i = 0; i < nSize; ++i ) {
  42. it = static_cast<value_type>( i );
  43. ASSERT_TRUE( q.push( it ));
  44. ASSERT_CONTAINER_SIZE( q, i + 1 );
  45. }
  46. ASSERT_FALSE( q.empty());
  47. ASSERT_CONTAINER_SIZE( q, nSize );
  48. for ( size_t i = 0; i < nSize; ++i ) {
  49. it = -1;
  50. ASSERT_TRUE( q.pop( it ));
  51. ASSERT_EQ( it, static_cast<value_type>( i ));
  52. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  53. }
  54. ASSERT_TRUE( q.empty());
  55. ASSERT_CONTAINER_SIZE( q, 0 );
  56. }
  57. // push/pop with lambda
  58. for ( unsigned pass = 0; pass < 3; ++pass ) {
  59. for ( size_t i = 0; i < nSize; ++i ) {
  60. it = static_cast<value_type>( i );
  61. ASSERT_NE( it, -1 );
  62. auto f = [&it]( value_type& dest ) { dest = it; it = -1; };
  63. if ( i & 1 )
  64. ASSERT_TRUE( q.enqueue_with( f ));
  65. else
  66. ASSERT_TRUE( q.push_with( f ));
  67. ASSERT_EQ( it, -1 );
  68. ASSERT_CONTAINER_SIZE( q, i + 1 );
  69. }
  70. ASSERT_FALSE( q.empty());
  71. ASSERT_CONTAINER_SIZE( q, nSize );
  72. for ( size_t i = 0; i < nSize; ++i ) {
  73. it = -1;
  74. auto f = [&it]( value_type& src ) { it = src; src = -1; };
  75. if ( i & 1 )
  76. ASSERT_TRUE( q.pop_with( f ));
  77. else
  78. ASSERT_TRUE( q.dequeue_with( f ));
  79. ASSERT_EQ( it, static_cast<value_type>( i ));
  80. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  81. }
  82. ASSERT_TRUE( q.empty());
  83. ASSERT_CONTAINER_SIZE( q, 0u );
  84. }
  85. for ( size_t i = 0; i < nSize; ++i ) {
  86. ASSERT_TRUE( q.push( static_cast<value_type>(i)));
  87. }
  88. ASSERT_FALSE( q.empty());
  89. ASSERT_CONTAINER_SIZE( q, nSize );
  90. // push in full queue
  91. ASSERT_FALSE( q.push( static_cast<int>(nSize * 2 )));
  92. ASSERT_FALSE( q.empty());
  93. ASSERT_CONTAINER_SIZE( q, nSize );
  94. it = static_cast<int>( nSize * 2 );
  95. ASSERT_FALSE( q.enqueue( it ));
  96. ASSERT_FALSE( q.empty());
  97. ASSERT_CONTAINER_SIZE( q, nSize );
  98. // clear
  99. q.clear();
  100. ASSERT_TRUE( q.empty());
  101. ASSERT_CONTAINER_SIZE( q, 0u );
  102. // pop from empty queue
  103. it = static_cast<int>(nSize * 2);
  104. ASSERT_FALSE( q.pop( it ));
  105. ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
  106. ASSERT_TRUE( q.empty());
  107. ASSERT_CONTAINER_SIZE( q, 0u );
  108. ASSERT_FALSE( q.dequeue( it ));
  109. ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
  110. ASSERT_TRUE( q.empty());
  111. ASSERT_CONTAINER_SIZE( q, 0u );
  112. }
  113. template <class Queue>
  114. void test_string( Queue& q )
  115. {
  116. std::string str[3];
  117. str[0] = "one";
  118. str[1] = "two";
  119. str[2] = "three";
  120. const size_t nSize = sizeof( str ) / sizeof( str[0] );
  121. // emplace
  122. for ( size_t i = 0; i < nSize; ++i ) {
  123. ASSERT_TRUE( q.emplace( str[i].c_str()));
  124. ASSERT_CONTAINER_SIZE( q, i + 1 );
  125. }
  126. ASSERT_FALSE( q.empty());
  127. ASSERT_CONTAINER_SIZE( q, nSize );
  128. {
  129. std::string s;
  130. auto f = [&s]( std::string& src ) {
  131. ASSERT_FALSE( src.empty());
  132. s = std::move( src );
  133. ASSERT_NE( s, src );
  134. };
  135. for ( size_t i = 0; i < nSize; ++i ) {
  136. if ( i & 1 )
  137. ASSERT_TRUE( q.pop_with( f ));
  138. else
  139. ASSERT_TRUE( q.dequeue_with( f ));
  140. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  141. ASSERT_EQ( s, str[i] );
  142. }
  143. }
  144. ASSERT_TRUE( q.empty());
  145. ASSERT_CONTAINER_SIZE( q, 0 );
  146. // move push
  147. for ( size_t i = 0; i < nSize; ++i ) {
  148. std::string s = str[i];
  149. ASSERT_FALSE( s.empty());
  150. if ( i & 1 )
  151. ASSERT_TRUE( q.enqueue( std::move( s )));
  152. else
  153. ASSERT_TRUE( q.push( std::move( s )));
  154. ASSERT_TRUE( s.empty());
  155. ASSERT_CONTAINER_SIZE( q, i + 1 );
  156. }
  157. ASSERT_FALSE( q.empty());
  158. ASSERT_CONTAINER_SIZE( q, nSize );
  159. for ( size_t i = 0; i < nSize; ++i ) {
  160. std::string s;
  161. ASSERT_TRUE( q.pop( s ));
  162. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  163. ASSERT_EQ( s, str[i] );
  164. }
  165. ASSERT_TRUE( q.empty());
  166. ASSERT_CONTAINER_SIZE( q, 0 );
  167. }
  168. };
  169. } // namespace cds_test
  170. #endif // CDSUNIT_QUEUE_TEST_BOUNDED_QUEUE_H