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/fcstack.h>
34 #include <boost/intrusive/list.hpp>
37 class IntrusiveFCStack : public ::testing::Test
40 template <typename Hook>
41 struct base_hook_item : public Hook
51 template <typename Hook>
52 struct member_hook_item
66 void operator ()( T * p )
72 template <class Stack>
75 typedef typename Stack::value_type value_type;
78 ASSERT_TRUE( stack.empty() );
80 value_type v1, v2, v3;
84 ASSERT_TRUE( stack.push( v1 ) );
85 ASSERT_TRUE( !stack.empty() );
86 ASSERT_TRUE( stack.push( v2 ) );
87 ASSERT_TRUE( !stack.empty() );
88 ASSERT_TRUE( stack.push( v3 ) );
89 ASSERT_TRUE( !stack.empty() );
93 ASSERT_TRUE( pv != nullptr );
94 ASSERT_EQ( pv->nVal, 3 );
95 ASSERT_TRUE( !stack.empty() );
97 ASSERT_TRUE( pv != nullptr );
98 ASSERT_EQ( pv->nVal, 2 );
99 ASSERT_TRUE( !stack.empty() );
101 ASSERT_TRUE( pv != nullptr );
102 ASSERT_EQ( pv->nVal, 1 );
103 ASSERT_TRUE( stack.empty() );
105 ASSERT_TRUE( pv == nullptr );
106 ASSERT_TRUE( stack.empty() );
108 if ( !std::is_same<typename Stack::disposer, cds::intrusive::opt::v::empty_disposer>::value ) {
109 int v1disp = v1.nDisposeCount;
110 int v2disp = v2.nDisposeCount;
111 int v3disp = v3.nDisposeCount;
113 ASSERT_TRUE( stack.push( v1 ));
114 ASSERT_TRUE( stack.push( v2 ));
115 ASSERT_TRUE( stack.push( v3 ));
118 ASSERT_TRUE( stack.empty() );
120 EXPECT_EQ( v1.nDisposeCount, v1disp);
121 EXPECT_EQ( v2.nDisposeCount, v2disp);
122 EXPECT_EQ( v3.nDisposeCount, v3disp);
124 ASSERT_TRUE( stack.push( v1 ) );
125 ASSERT_TRUE( stack.push( v2 ) );
126 ASSERT_TRUE( stack.push( v3 ) );
127 ASSERT_TRUE( !stack.empty() );
130 ASSERT_TRUE( stack.empty() );
132 EXPECT_EQ( v1.nDisposeCount, v1disp + 1 );
133 EXPECT_EQ( v2.nDisposeCount, v2disp + 1 );
134 EXPECT_EQ( v3.nDisposeCount, v3disp + 1 );
139 TEST_F( IntrusiveFCStack, slist )
141 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
142 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type > > stack_type;
146 TEST_F( IntrusiveFCStack, slist_disposer )
148 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
149 struct stack_traits : public cds::intrusive::fcstack::traits
151 typedef mock_disposer disposer;
153 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
157 TEST_F( IntrusiveFCStack, slist_mutex )
159 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
160 struct stack_traits : public cds::intrusive::fcstack::traits
162 typedef std::mutex lock_type;
164 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
168 TEST_F( IntrusiveFCStack, slist_elimination )
170 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
171 struct stack_traits : public
172 cds::intrusive::fcstack::make_traits <
173 cds::opt::enable_elimination < true >
176 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
180 TEST_F( IntrusiveFCStack, slist_elimination_disposer )
182 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
183 struct stack_traits : public
184 cds::intrusive::fcstack::make_traits <
185 cds::opt::enable_elimination < true >,
186 cds::intrusive::opt::disposer< mock_disposer >
189 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >, stack_traits > stack_type;
193 TEST_F( IntrusiveFCStack, slist_elimination_stat )
195 typedef base_hook_item< boost::intrusive::slist_base_hook<> > value_type;
196 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type >,
197 cds::intrusive::fcstack::make_traits<
198 cds::opt::enable_elimination< true >
199 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
205 TEST_F( IntrusiveFCStack, slist_member )
207 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
208 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
210 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option > > stack_type;
214 TEST_F( IntrusiveFCStack, slist_member_disposer )
216 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
217 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
218 struct stack_traits : public cds::intrusive::fcstack::traits
220 typedef mock_disposer disposer;
223 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >, stack_traits > stack_type;
227 TEST_F( IntrusiveFCStack, slist_member_elimination )
229 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
230 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
232 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >,
233 cds::intrusive::fcstack::make_traits<
234 cds::opt::enable_elimination< true >
240 TEST_F( IntrusiveFCStack, slist_member_elimination_stat )
242 typedef member_hook_item< boost::intrusive::slist_member_hook<> > value_type;
243 typedef boost::intrusive::member_hook<value_type, boost::intrusive::slist_member_hook<>, &value_type::hMember> member_option;
245 typedef cds::intrusive::FCStack< value_type, boost::intrusive::slist< value_type, member_option >,
246 cds::intrusive::fcstack::make_traits<
247 cds::opt::enable_elimination< true >
248 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
254 TEST_F( IntrusiveFCStack, list )
256 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
257 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type > > stack_type;
261 TEST_F( IntrusiveFCStack, list_mutex )
263 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
264 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
265 cds::intrusive::fcstack::make_traits<
266 cds::opt::lock_type< std::mutex >
273 TEST_F( IntrusiveFCStack, list_elimination )
275 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
276 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
277 cds::intrusive::fcstack::make_traits<
278 cds::opt::enable_elimination< true >
284 TEST_F( IntrusiveFCStack, list_elimination_stat )
286 typedef base_hook_item< boost::intrusive::list_base_hook<> > value_type;
287 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type >,
288 cds::intrusive::fcstack::make_traits<
289 cds::opt::enable_elimination< true >
290 , cds::opt::stat< cds::intrusive::fcstack::stat<> >
296 TEST_F( IntrusiveFCStack, list_member )
298 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
299 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
301 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option > > stack_type;
305 TEST_F( IntrusiveFCStack, list_member_elimination )
307 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
308 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
310 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option >,
311 cds::intrusive::fcstack::make_traits<
312 cds::opt::enable_elimination< true >
318 TEST_F( IntrusiveFCStack, list_member_elimination_stat )
320 typedef member_hook_item< boost::intrusive::list_member_hook<> > value_type;
321 typedef boost::intrusive::member_hook<value_type, boost::intrusive::list_member_hook<>, &value_type::hMember> member_option;
323 typedef cds::intrusive::FCStack< value_type, boost::intrusive::list< value_type, member_option >,
324 cds::intrusive::fcstack::make_traits<
325 cds::opt::enable_elimination< true >
326 , cds::opt::stat< cds::intrusive::fcstack::stat<> >