2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <gtest/gtest.h>
32 #include <cds/intrusive/fcqueue.h>
35 #include <boost/intrusive/slist.hpp>
39 class IntrusiveFCQueue : public ::testing::Test
42 template <typename Hook>
43 struct base_hook_item : public Hook
53 template <typename Hook>
54 struct member_hook_item
68 void operator ()( T * p )
74 template <typename Queue>
77 typedef typename Queue::value_type value_type;
79 size_t const nSize = 100;
81 std::vector<value_type> arr;
83 for ( size_t i = 0; i < nSize; ++i )
84 arr[i].nVal = static_cast<int>(i);
86 ASSERT_TRUE( q.empty() );
87 ASSERT_EQ( q.size(), 0 );
89 // pop from empty queue
91 ASSERT_TRUE( pv == nullptr );
92 ASSERT_TRUE( q.empty() );
93 ASSERT_EQ( q.size(), 0 );
96 ASSERT_TRUE( pv == nullptr );
97 ASSERT_TRUE( q.empty() );
98 ASSERT_EQ( q.size(), 0 );
101 for ( size_t i = 0; i < nSize; ++i ) {
106 ASSERT_FALSE( q.empty() );
107 ASSERT_EQ( q.size(), i + 1 );
110 for ( size_t i = 0; i < nSize; ++i ) {
111 ASSERT_FALSE( q.empty() );
112 ASSERT_EQ( q.size(), nSize - i );
117 ASSERT_FALSE( pv == nullptr );
118 ASSERT_EQ( pv->nVal, static_cast<int>(i) );
120 ASSERT_TRUE( q.empty() );
121 ASSERT_EQ( q.size(), 0 );
123 // pop() doesn't call disposer
124 for ( size_t i = 0; i < nSize; ++i ) {
125 ASSERT_EQ( arr[i].nDisposeCount, 0 );
128 // clear with disposer
129 for ( size_t i = 0; i < nSize; ++i )
132 ASSERT_FALSE( q.empty() );
133 ASSERT_EQ( q.size(), nSize );
136 ASSERT_TRUE( q.empty() );
137 ASSERT_EQ( q.size(), 0 );
139 for ( size_t i = 0; i < nSize; ++i ) {
140 ASSERT_EQ( arr[i].nDisposeCount, 1 );
143 // clear without disposer
144 for ( size_t i = 0; i < nSize; ++i )
148 ASSERT_TRUE( q.empty() );
149 ASSERT_EQ( q.size(), 0 );
151 for ( size_t i = 0; i < nSize; ++i ) {
152 ASSERT_EQ( arr[i].nDisposeCount, 1 );
157 TEST_F( IntrusiveFCQueue, base )
159 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
160 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >,
161 cds::intrusive::fcqueue::make_traits<
162 cds::intrusive::opt::disposer< disposer >
170 TEST_F( IntrusiveFCQueue, base_mutex )
172 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
173 struct traits : public cds::intrusive::fcqueue::traits
175 typedef IntrusiveFCQueue::disposer disposer;
176 typedef std::mutex lock_type;
177 typedef cds::intrusive::fcqueue::stat<> stat;
179 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >, traits > queue_type;
185 TEST_F( IntrusiveFCQueue, base_elimination )
187 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
188 struct traits : public
189 cds::intrusive::fcqueue::make_traits <
190 cds::intrusive::opt::disposer< disposer >
191 , cds::opt::enable_elimination < true >
194 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type >, traits > queue_type;
200 TEST_F( IntrusiveFCQueue, member )
202 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
203 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
205 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
206 cds::intrusive::fcqueue::make_traits<
207 cds::intrusive::opt::disposer< disposer >
215 TEST_F( IntrusiveFCQueue, member_mutex )
217 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
218 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
220 struct traits : public cds::intrusive::fcqueue::traits
222 typedef IntrusiveFCQueue::disposer disposer;
223 typedef std::mutex lock_type;
224 typedef cds::intrusive::fcqueue::stat<> stat;
226 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >, traits > queue_type;
232 TEST_F( IntrusiveFCQueue, member_elimination )
234 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
235 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
237 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::list< value_type, member_option >,
238 cds::intrusive::fcqueue::make_traits<
239 cds::intrusive::opt::disposer< disposer >
240 ,cds::opt::enable_elimination< true >
248 TEST_F( IntrusiveFCQueue, slist_base )
250 typedef base_hook_item< boost::intrusive::slist_base_hook<>> value_type;
251 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::slist< value_type, boost::intrusive::cache_last< true >>,
252 cds::intrusive::fcqueue::make_traits<
253 cds::intrusive::opt::disposer< disposer >
261 TEST_F( IntrusiveFCQueue, slist_base_elimination )
263 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
264 struct traits : public
265 cds::intrusive::fcqueue::make_traits <
266 cds::intrusive::opt::disposer< disposer >
267 , cds::opt::enable_elimination < true >
268 , cds::opt::lock_type< std::mutex >
271 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::slist< value_type, boost::intrusive::cache_last< true >>, traits > queue_type;
277 TEST_F( IntrusiveFCQueue, slist_member )
279 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
280 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
282 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::slist< value_type, member_option, boost::intrusive::cache_last< true >>,
283 cds::intrusive::fcqueue::make_traits<
284 cds::intrusive::opt::disposer< disposer >
292 TEST_F( IntrusiveFCQueue, slist_member_elimination )
294 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
295 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
297 typedef cds::intrusive::FCQueue< value_type, boost::intrusive::slist< value_type, member_option, boost::intrusive::cache_last< true >>,
298 cds::intrusive::fcqueue::make_traits<
299 cds::intrusive::opt::disposer< disposer >
300 ,cds::opt::enable_elimination< true >