test_intrusive_treiber_stack.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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_STACK_INTRUSIVE_TREIBER_STACK_H
  6. #define CDSUNIT_STACK_INTRUSIVE_TREIBER_STACK_H
  7. #include <cds_test/ext_gtest.h>
  8. #include <cds/intrusive/details/single_link_struct.h>
  9. namespace cds_test {
  10. class IntrusiveTreiberStack : public ::testing::Test
  11. {
  12. protected:
  13. template <typename GC>
  14. struct base_hook_item : public cds::intrusive::single_link::node< GC >
  15. {
  16. int nVal;
  17. int nDisposeCount;
  18. base_hook_item()
  19. : nDisposeCount( 0 )
  20. {}
  21. };
  22. template <typename GC>
  23. struct member_hook_item
  24. {
  25. int nVal;
  26. int nDisposeCount;
  27. cds::intrusive::single_link::node< GC > hMember;
  28. member_hook_item()
  29. : nDisposeCount( 0 )
  30. {}
  31. };
  32. struct mock_disposer
  33. {
  34. template <typename T>
  35. void operator ()( T * p )
  36. {
  37. ++p->nDisposeCount;
  38. }
  39. };
  40. template <typename Stack>
  41. void test( Stack& stack )
  42. {
  43. typedef typename Stack::value_type value_type;
  44. ASSERT_TRUE( stack.empty());
  45. value_type v1, v2, v3;
  46. v1.nVal = 1;
  47. v2.nVal = 2;
  48. v3.nVal = 3;
  49. ASSERT_TRUE( stack.push( v1 ));
  50. ASSERT_TRUE( !stack.empty());
  51. ASSERT_TRUE( stack.push( v2 ));
  52. ASSERT_TRUE( !stack.empty());
  53. ASSERT_TRUE( stack.push( v3 ));
  54. ASSERT_TRUE( !stack.empty());
  55. value_type * pv;
  56. pv = stack.pop();
  57. ASSERT_NE( pv, nullptr );
  58. ASSERT_EQ( pv, &v3 );
  59. ASSERT_EQ( pv->nVal, 3 );
  60. ASSERT_TRUE( !stack.empty());
  61. pv = stack.pop();
  62. ASSERT_NE( pv, nullptr );
  63. ASSERT_EQ( pv, &v2 );
  64. ASSERT_EQ( pv->nVal, 2 );
  65. ASSERT_TRUE( !stack.empty());
  66. pv = stack.pop();
  67. ASSERT_NE( pv, nullptr );
  68. ASSERT_EQ( pv, &v1 );
  69. ASSERT_EQ( pv->nVal, 1 );
  70. ASSERT_TRUE( stack.empty());
  71. pv = stack.pop();
  72. ASSERT_EQ( pv, nullptr );
  73. ASSERT_TRUE( stack.empty());
  74. ASSERT_EQ( v1.nDisposeCount, 0 );
  75. ASSERT_EQ( v2.nDisposeCount, 0 );
  76. ASSERT_EQ( v3.nDisposeCount, 0 );
  77. stack.push( v1 );
  78. stack.push( v2 );
  79. stack.push( v3 );
  80. stack.clear();
  81. ASSERT_TRUE( stack.empty());
  82. Stack::gc::scan();
  83. if ( !std::is_same<typename Stack::disposer, cds::intrusive::opt::v::empty_disposer>::value ) {
  84. ASSERT_EQ( v1.nDisposeCount, 1 );
  85. ASSERT_EQ( v2.nDisposeCount, 1 );
  86. ASSERT_EQ( v3.nDisposeCount, 1 );
  87. }
  88. }
  89. };
  90. } // namespace cds_test
  91. #endif // CDSUNIT_STACK_INTRUSIVE_TREIBER_STACK_H