Merge branch 'dev'
[libcds.git] / test / unit / map / test_map_nogc.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
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.
18
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.     
29 */
30
31 #ifndef CDSUNIT_MAP_TEST_MAP_NOGC_H
32 #define CDSUNIT_MAP_TEST_MAP_NOGC_H
33
34 #include "test_map_data.h"
35
36 // forward declaration
37 namespace cds { namespace container {} }
38
39 namespace cds_test {
40
41     class container_map_nogc: public map_fixture
42     {
43     public:
44         static size_t const kSize = 1000;
45
46     protected:
47         template <class Map>
48         void test( Map& m )
49         {
50             // Precondition: map is empty
51             // Postcondition: map is empty
52
53             ASSERT_TRUE( m.empty());
54             ASSERT_CONTAINER_SIZE( m, 0 );
55
56             typedef typename Map::value_type map_pair;
57             typedef typename Map::iterator   iterator;
58             typedef typename Map::const_iterator const_iterator;
59             size_t const kkSize = kSize;
60
61             std::vector<key_type> arrKeys;
62             for ( int i = 0; i < static_cast<int>(kkSize); ++i )
63                 arrKeys.push_back( key_type( i ));
64             shuffle( arrKeys.begin(), arrKeys.end());
65
66             std::vector< value_type > arrVals;
67             for ( size_t i = 0; i < kkSize; ++i ) {
68                 value_type val;
69                 val.nVal = static_cast<int>( i );
70                 val.strVal = std::to_string( i );
71                 arrVals.push_back( val );
72             }
73
74             // insert/find
75             for ( auto const& i : arrKeys ) {
76                 value_type const& val( arrVals.at( i.nKey ));
77
78                 ASSERT_FALSE( m.contains( i.nKey ) != m.end());
79                 ASSERT_FALSE( m.contains( i ) != m.end());
80                 ASSERT_FALSE( m.contains( other_item( i.nKey ), other_less()) != m.end());
81
82                 std::pair< iterator, bool > updResult;
83                 iterator it;
84                 switch ( i.nKey % 16 ) {
85                 case 0:
86                     it = m.insert( i );
87                     ASSERT_FALSE( it == m.end());
88                     ASSERT_TRUE( m.insert( i ) == m.end());
89                     it->second.nVal = it->first.nKey;
90                     it->second.strVal = std::to_string( it->first.nKey );
91                     break;
92                 case 1:
93                     it = m.insert( i.nKey );
94                     ASSERT_FALSE( it == m.end() );
95                     ASSERT_TRUE( m.insert( i.nKey ) == m.end());
96                     it->second.nVal = it->first.nKey;
97                     it->second.strVal = std::to_string( it->first.nKey );
98                     break;
99                 case 2:
100                     it = m.insert( std::to_string( i.nKey ));
101                     ASSERT_FALSE( it == m.end() );
102                     ASSERT_TRUE( m.insert( std::to_string( i.nKey )) == m.end());
103                     it->second.nVal = it->first.nKey;
104                     it->second.strVal = std::to_string( it->first.nKey );
105                     break;
106                 case 3:
107                     it = m.insert( i, val );
108                     ASSERT_FALSE( it == m.end() );
109                     ASSERT_TRUE( m.insert( i, val ) == m.end());
110                     break;
111                 case 4:
112                     it = m.insert( i.nKey, val.strVal );
113                     ASSERT_FALSE( it == m.end() );
114                     ASSERT_TRUE( m.insert( i.nKey, val.strVal ) == m.end());
115                     break;
116                 case 5:
117                     it = m.insert( val.strVal, i.nKey );
118                     ASSERT_FALSE( it == m.end() );
119                     ASSERT_TRUE( m.insert( val.strVal, i.nKey ) == m.end());
120                     break;
121                 case 6:
122                     it = m.insert_with( i, []( map_pair& v ) {
123                         v.second.nVal = v.first.nKey;
124                         v.second.strVal = std::to_string( v.first.nKey );
125                     } );
126                     ASSERT_FALSE( it == m.end() );
127                     ASSERT_TRUE( m.insert_with( i, []( map_pair& v ) {
128                         EXPECT_TRUE( false );
129                     } ) == m.end());
130                     break;
131                 case 7:
132                     it = m.insert_with( i.nKey, []( map_pair& v ) {
133                         v.second.nVal = v.first.nKey;
134                         v.second.strVal = std::to_string( v.first.nKey );
135                     } );
136                     ASSERT_FALSE( it == m.end() );
137                     ASSERT_TRUE( m.insert_with( i.nKey, []( map_pair& v ) {
138                         EXPECT_TRUE( false );
139                     } ) == m.end());
140                     break;
141                 case 8:
142                     it = m.insert_with( val.strVal, []( map_pair& v ) {
143                         v.second.nVal = v.first.nKey;
144                         v.second.strVal = std::to_string( v.first.nKey );
145                     } );
146                     ASSERT_FALSE( it == m.end() );
147                     ASSERT_TRUE( m.insert_with( val.strVal, []( map_pair& v ) {
148                         EXPECT_TRUE( false );
149                     } ) == m.end());
150                     break;
151                 case 9:
152                     updResult = m.update( i.nKey, false );
153                     ASSERT_TRUE( updResult.first == m.end() );
154                     ASSERT_FALSE( updResult.second );
155
156                     updResult = m.update( i.nKey );
157                     ASSERT_TRUE( updResult.first != m.end());
158                     ASSERT_TRUE( updResult.second );
159                     updResult.first->second.nVal = updResult.first->first.nKey;
160
161                     updResult = m.update( i.nKey, false );
162                     ASSERT_TRUE( updResult.first != m.end() );
163                     ASSERT_FALSE( updResult.second );
164                     EXPECT_EQ( updResult.first->first.nKey, updResult.first->second.nVal );
165                     updResult.first->second.strVal = std::to_string( updResult.first->second.nVal );
166                     break;
167                 case 10:
168                     updResult = m.update( i, false );
169                     ASSERT_TRUE( updResult.first == m.end() );
170                     ASSERT_FALSE( updResult.second );
171
172                     updResult = m.update( i );
173                     ASSERT_TRUE( updResult.first != m.end());
174                     ASSERT_TRUE( updResult.second );
175                     updResult.first->second.nVal = updResult.first->first.nKey;
176
177                     updResult = m.update( i );
178                     ASSERT_TRUE( updResult.first != m.end());
179                     ASSERT_FALSE( updResult.second );
180                     EXPECT_EQ( updResult.first->first.nKey, updResult.first->second.nVal );
181                     updResult.first->second.strVal = std::to_string( updResult.first->second.nVal );
182                     break;
183                 case 11:
184                     updResult = m.update( val.strVal, false );
185                     ASSERT_TRUE( updResult.first == m.end());
186                     ASSERT_FALSE( updResult.second );
187
188                     updResult = m.update( val.strVal );
189                     ASSERT_TRUE( updResult.first != m.end());
190                     ASSERT_TRUE( updResult.second );
191                     updResult.first->second.nVal = updResult.first->first.nKey;
192
193                     updResult = m.update( val.strVal, false );
194                     ASSERT_TRUE( updResult.first != m.end());
195                     ASSERT_FALSE( updResult.second );
196                     EXPECT_EQ( updResult.first->first.nKey, updResult.first->second.nVal );
197                     updResult.first->second.strVal = std::to_string( updResult.first->second.nVal );
198                     break;
199                 case 12:
200                     it = m.emplace( i.nKey );
201                     ASSERT_TRUE( it != m.end());
202                     ASSERT_FALSE( m.emplace( i.nKey ) != m.end());
203                     it->second.nVal = it->first.nKey;
204                     it->second.strVal = std::to_string( it->first.nKey );
205                     break;
206                 case 13:
207                     it = m.emplace( i, i.nKey );
208                     ASSERT_TRUE( it != m.end() );
209                     ASSERT_FALSE( m.emplace( i, i.nKey ) != m.end());
210                     break;
211                 case 14:
212                     {
213                         std::string str = val.strVal;
214                         it = m.emplace( i, std::move( str ));
215                         ASSERT_TRUE( it != m.end() );
216                         ASSERT_TRUE( str.empty());
217                         str = val.strVal;
218                         ASSERT_FALSE( m.emplace( i, std::move( str )) != m.end());
219                         ASSERT_TRUE( str.empty());
220                     }
221                     break;
222                 case 15:
223                     {
224                         std::string str = val.strVal;
225                         it = m.emplace( i, i.nKey, std::move( str ));
226                         ASSERT_TRUE( it != m.end() );
227                         ASSERT_TRUE( str.empty());
228                         str = val.strVal;
229                         ASSERT_FALSE( m.emplace( i, i.nKey, std::move( str )) != m.end());
230                         ASSERT_TRUE( str.empty());
231                     }
232                     break;
233                 }
234
235                 it = m.contains( i.nKey );
236                 ASSERT_TRUE( it != m.end());
237                 ASSERT_TRUE( m.contains( i ) == it );
238                 ASSERT_TRUE( m.contains( other_item( i.nKey ), other_less()) == it );
239                 EXPECT_EQ( it->first.nKey, it->second.nVal );
240                 EXPECT_EQ( std::to_string( it->first.nKey ), it->second.strVal );
241             }
242             ASSERT_FALSE( m.empty() );
243             ASSERT_CONTAINER_SIZE( m, kkSize );
244             ASSERT_FALSE( m.begin() == m.end() );
245             ASSERT_FALSE( m.cbegin() == m.cend() );
246
247             // clear
248
249             m.clear();
250
251             ASSERT_TRUE( m.empty() );
252             ASSERT_CONTAINER_SIZE( m, 0 );
253             ASSERT_TRUE( m.begin() == m.end() );
254             ASSERT_TRUE( m.cbegin() == m.cend() );
255         }
256     };
257
258 } // namespace cds_test
259
260 #endif // #ifndef CDSUNIT_MAP_TEST_MAP_NOGC_H