3 #include "cppunit/cppunit_proxy.h"
4 #include <cds/intrusive/fcqueue.h>
8 class TestIntrusiveFCQueue: public CppUnitMini::TestCase
10 template <typename Hook>
11 struct base_hook_item: public Hook
21 template <typename Hook>
22 struct member_hook_item
36 void operator ()( T * p )
42 template <typename Queue>
49 template <class Queue>
50 void test_with( Queue& q )
52 typedef typename Queue::value_type value_type;
53 value_type v1, v2, v3;
54 CPPUNIT_ASSERT( q.empty() );
59 CPPUNIT_ASSERT( q.push(v1));
60 CPPUNIT_ASSERT( !q.empty() );
61 CPPUNIT_ASSERT( q.push(v2));
62 CPPUNIT_ASSERT( !q.empty() );
63 CPPUNIT_ASSERT( q.push(v3));
64 CPPUNIT_ASSERT( !q.empty() );
66 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
67 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
68 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
72 CPPUNIT_ASSERT( pv != nullptr );
73 CPPUNIT_ASSERT( pv->nVal == 1 );
74 CPPUNIT_ASSERT( !q.empty() );
75 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
76 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
77 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
80 CPPUNIT_ASSERT( pv != nullptr );
81 CPPUNIT_ASSERT( pv->nVal == 2 );
82 CPPUNIT_ASSERT( !q.empty() );
83 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
84 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
85 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
88 CPPUNIT_ASSERT( pv != nullptr );
89 CPPUNIT_ASSERT( pv->nVal == 3 );
90 CPPUNIT_ASSERT( q.empty() );
91 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
92 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
93 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
96 CPPUNIT_ASSERT( pv == nullptr );
97 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
98 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
99 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
101 CPPUNIT_ASSERT( q.enqueue(v1));
102 CPPUNIT_ASSERT( !q.empty() );
103 CPPUNIT_ASSERT( q.enqueue(v2));
104 CPPUNIT_ASSERT( !q.empty() );
105 CPPUNIT_ASSERT( q.enqueue(v3));
106 CPPUNIT_ASSERT( !q.empty() );
108 CPPUNIT_CHECK( v1.nDisposeCount == 0 );
109 CPPUNIT_CHECK( v2.nDisposeCount == 0 );
110 CPPUNIT_CHECK( v3.nDisposeCount == 0 );
111 q.clear( true ); // call disposer
112 CPPUNIT_CHECK( q.empty() );
113 CPPUNIT_CHECK( v1.nDisposeCount == 1 );
114 CPPUNIT_CHECK( v2.nDisposeCount == 1 );
115 CPPUNIT_CHECK( v3.nDisposeCount == 1 );
117 CPPUNIT_ASSERT( q.push(v1));
118 CPPUNIT_ASSERT( !q.empty() );
119 CPPUNIT_ASSERT( q.push(v2));
120 CPPUNIT_ASSERT( !q.empty() );
121 CPPUNIT_ASSERT( q.push(v3));
122 CPPUNIT_ASSERT( !q.empty() );
123 q.clear( false ); // no disposer called
124 CPPUNIT_CHECK( q.empty() );
125 CPPUNIT_CHECK( v1.nDisposeCount == 1 );
126 CPPUNIT_CHECK( v2.nDisposeCount == 1 );
127 CPPUNIT_CHECK( v3.nDisposeCount == 1 );
131 void FCQueue_base_stat();
132 void FCQueue_base_elimination();
133 void FCQueue_base_elimination_mutex();
134 void FCQueue_base_seqcst();
135 void FCQueue_member();
136 void FCQueue_member_stat();
137 void FCQueue_member_elimination();
138 void FCQueue_member_elimination_mutex();
139 void FCQueue_member_seqcst();
141 CPPUNIT_TEST_SUITE(TestIntrusiveFCQueue)
142 CPPUNIT_TEST(FCQueue_base)
143 CPPUNIT_TEST(FCQueue_base_stat)
144 CPPUNIT_TEST(FCQueue_base_elimination)
145 CPPUNIT_TEST(FCQueue_base_elimination_mutex)
146 CPPUNIT_TEST(FCQueue_base_seqcst)
147 CPPUNIT_TEST(FCQueue_member)
148 CPPUNIT_TEST(FCQueue_member_stat)
149 CPPUNIT_TEST(FCQueue_member_elimination)
150 CPPUNIT_TEST(FCQueue_member_elimination_mutex)
151 CPPUNIT_TEST(FCQueue_member_seqcst)
152 CPPUNIT_TEST_SUITE_END()
156 void TestIntrusiveFCQueue::FCQueue_base()
158 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
159 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >,
160 cds::intrusive::fcqueue::make_traits<
161 cds::intrusive::opt::disposer< disposer >
168 void TestIntrusiveFCQueue::FCQueue_base_stat()
170 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
171 struct queue_traits : public cds::intrusive::fcqueue::traits
173 typedef TestIntrusiveFCQueue::disposer disposer;
174 typedef cds::intrusive::fcqueue::stat<> stat;
176 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >, queue_traits > queue_type;
181 void TestIntrusiveFCQueue::FCQueue_base_elimination()
183 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
184 struct queue_traits : public
185 cds::intrusive::fcqueue::make_traits <
186 cds::intrusive::opt::disposer< disposer >
187 ,cds::opt::enable_elimination < true >
190 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >, queue_traits > queue_type;
195 void TestIntrusiveFCQueue::FCQueue_base_elimination_mutex()
197 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
198 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >,
199 cds::intrusive::fcqueue::make_traits<
200 cds::intrusive::opt::disposer< disposer >
201 ,cds::opt::enable_elimination< true >
202 ,cds::opt::lock_type< std::mutex >
209 void TestIntrusiveFCQueue::FCQueue_base_seqcst()
211 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
212 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >,
213 cds::intrusive::fcqueue::make_traits<
214 cds::intrusive::opt::disposer< disposer >
215 ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
222 void TestIntrusiveFCQueue::FCQueue_member()
224 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
225 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
227 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
228 cds::intrusive::fcqueue::make_traits<
229 cds::intrusive::opt::disposer< disposer >
236 void TestIntrusiveFCQueue::FCQueue_member_stat()
238 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
239 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
241 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
242 cds::intrusive::fcqueue::make_traits<
243 cds::intrusive::opt::disposer< disposer >
244 ,cds::opt::stat< cds::intrusive::fcqueue::stat<> >
251 void TestIntrusiveFCQueue::FCQueue_member_elimination()
253 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
254 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
256 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
257 cds::intrusive::fcqueue::make_traits<
258 cds::intrusive::opt::disposer< disposer >
259 ,cds::opt::enable_elimination< true >
266 void TestIntrusiveFCQueue::FCQueue_member_elimination_mutex()
268 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
269 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
271 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
272 cds::intrusive::fcqueue::make_traits<
273 cds::intrusive::opt::disposer< disposer >
274 ,cds::opt::enable_elimination< true >
275 ,cds::opt::lock_type< std::mutex >
282 void TestIntrusiveFCQueue::FCQueue_member_seqcst()
284 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
285 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
287 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
288 cds::intrusive::fcqueue::make_traits<
289 cds::intrusive::opt::disposer< disposer >
290 ,cds::opt::memory_model< cds::opt::v::sequential_consistent >
299 CPPUNIT_TEST_SUITE_REGISTRATION(queue::TestIntrusiveFCQueue);