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 #ifndef CDSUNIT_MAP_TEST_MAP_H
32 #define CDSUNIT_MAP_TEST_MAP_H
34 #include <cds_test/check_size.h>
35 #include <cds_test/fixture.h>
37 #include <cds/opt/hash.h>
39 // forward declaration
40 namespace cds { namespace container {} }
44 class container_map: public fixture
47 static size_t const kSize = 1000;
52 explicit key_type( int n )
56 explicit key_type( std::string const& str )
57 : nKey( std::stoi( str ))
60 key_type( key_type const& s )
73 explicit value_type( int n )
75 , strVal( std::to_string( n ))
78 explicit value_type( std::string const& str )
79 : nVal( std::stoi( str ))
83 explicit value_type( std::string&& str )
84 : nVal( std::stoi( str ))
85 , strVal( std::move( str ))
88 value_type( int n, std::string const& str )
93 value_type( int n, std::string&& str )
95 , strVal( std::move( str ))
98 value_type( value_type&& v )
100 , strVal( std::move( v.strVal ))
103 value_type( value_type const& v )
108 value_type& operator=( value_type const& v )
117 value_type& operator=( value_type&& v )
121 strVal = std::move( v.strVal );
127 typedef std::pair<key_type const, value_type> pair_type;
131 bool operator ()( key_type const& v1, key_type const& v2 ) const
133 return v1.nKey < v2.nKey;
136 bool operator ()( key_type const& v1, int v2 ) const
141 bool operator ()( int v1, key_type const& v2 ) const
146 bool operator ()( key_type const& v1, std::string const& v2 ) const
148 return v1.nKey < std::stoi(v2 );
151 bool operator ()( std::string const& v1, key_type const& v2 ) const
153 return std::stoi( v1 ) < v2.nKey;
158 int operator ()( key_type const& v1, key_type const& v2 ) const
160 if ( v1.nKey < v2.nKey )
162 return v1.nKey > v2.nKey ? 1 : 0;
165 int operator ()( key_type const& v1, int v2 ) const
169 return v1.nKey > v2 ? 1 : 0;
172 int operator ()( int v1, key_type const& v2 ) const
176 return v1 > v2.nKey ? 1 : 0;
179 int operator ()( key_type const& v1, std::string const& v2 ) const
181 int n2 = std::stoi( v2 );
184 return v1.nKey > n2 ? 1 : 0;
187 int operator ()( std::string const& v1, key_type const& v2 ) const
189 int n1 = std::stoi( v1 );
192 return n1 > v2.nKey ? 1 : 0;
197 size_t operator()( int i ) const
199 return cds::opt::v::hash<int>()( i );
202 size_t operator()( std::string const& str ) const
204 return cds::opt::v::hash<int>()( std::stoi( str ));
207 template <typename T>
208 size_t operator()( T const& i ) const
210 return cds::opt::v::hash<int>()(i.nKey);
217 other_item( int key )
224 bool operator ()( key_type const& v1, other_item const& v2 ) const
226 return v1.nKey < v2.nKey;
228 bool operator ()( other_item const& v1, key_type const& v2 ) const
230 return v1.nKey < v2.nKey;
238 // Precondition: map is empty
239 // Postcondition: map is empty
241 ASSERT_TRUE( m.empty());
242 ASSERT_CONTAINER_SIZE( m, 0 );
244 typedef typename Map::value_type map_pair;
245 size_t const kkSize = kSize;
247 std::vector<key_type> arrKeys;
248 for ( int i = 0; i < static_cast<int>(kkSize); ++i )
249 arrKeys.push_back( key_type( i ));
250 shuffle( arrKeys.begin(), arrKeys.end());
252 std::vector< value_type > arrVals;
253 for ( size_t i = 0; i < kkSize; ++i ) {
255 val.nVal = static_cast<int>( i );
256 val.strVal = std::to_string( i );
257 arrVals.push_back( val );
261 for ( auto const& i : arrKeys ) {
262 value_type const& val( arrVals.at( i.nKey ));
264 ASSERT_FALSE( m.contains( i.nKey ));
265 ASSERT_FALSE( m.contains( i ));
266 ASSERT_FALSE( m.contains( other_item( i.nKey ), other_less()));
267 ASSERT_FALSE( m.find( i, []( map_pair const& ) {
268 ASSERT_TRUE( false );
270 ASSERT_FALSE( m.find( i.nKey, []( map_pair const& ) {
271 EXPECT_TRUE( false );
273 ASSERT_FALSE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& ) {
274 EXPECT_TRUE( false );
277 std::pair< bool, bool > updResult;
279 switch ( i.nKey % 16 ) {
281 ASSERT_TRUE( m.insert( i ));
282 ASSERT_FALSE( m.insert( i ));
283 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
284 v.second.nVal = v.first.nKey;
285 v.second.strVal = std::to_string( v.first.nKey );
289 ASSERT_TRUE( m.insert( i.nKey ));
290 ASSERT_FALSE( m.insert( i.nKey ));
291 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
292 v.second.nVal = v.first.nKey;
293 v.second.strVal = std::to_string( v.first.nKey );
297 ASSERT_TRUE( m.insert( std::to_string( i.nKey )));
298 ASSERT_FALSE( m.insert( std::to_string( i.nKey )));
299 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
300 v.second.nVal = v.first.nKey;
301 v.second.strVal = std::to_string( v.first.nKey );
305 ASSERT_TRUE( m.insert( i, val ));
306 ASSERT_FALSE( m.insert( i, val ));
309 ASSERT_TRUE( m.insert( i.nKey, val.strVal ));
310 ASSERT_FALSE( m.insert( i.nKey, val.strVal ));
313 ASSERT_TRUE( m.insert( val.strVal, i.nKey ));
314 ASSERT_FALSE( m.insert( val.strVal, i.nKey ));
317 ASSERT_TRUE( m.insert_with( i, []( map_pair& v ) {
318 v.second.nVal = v.first.nKey;
319 v.second.strVal = std::to_string( v.first.nKey );
321 ASSERT_FALSE( m.insert_with( i, []( map_pair& v ) {
322 EXPECT_TRUE( false );
326 ASSERT_TRUE( m.insert_with( i.nKey, []( map_pair& v ) {
327 v.second.nVal = v.first.nKey;
328 v.second.strVal = std::to_string( v.first.nKey );
330 ASSERT_FALSE( m.insert_with( i.nKey, []( map_pair& v ) {
331 EXPECT_TRUE( false );
335 ASSERT_TRUE( m.insert_with( val.strVal, []( map_pair& v ) {
336 v.second.nVal = v.first.nKey;
337 v.second.strVal = std::to_string( v.first.nKey );
339 ASSERT_FALSE( m.insert_with( val.strVal, []( map_pair& v ) {
340 EXPECT_TRUE( false );
344 updResult = m.update( i.nKey, []( bool, map_pair& ) {
345 EXPECT_TRUE( false );
347 ASSERT_FALSE( updResult.first );
348 ASSERT_FALSE( updResult.second );
350 updResult = m.update( i.nKey, []( bool bNew, map_pair& v ) {
352 v.second.nVal = v.first.nKey;
354 ASSERT_TRUE( updResult.first );
355 ASSERT_TRUE( updResult.second );
357 updResult = m.update( i.nKey, []( bool bNew, map_pair& v ) {
358 EXPECT_FALSE( bNew );
359 EXPECT_EQ( v.first.nKey, v.second.nVal );
360 v.second.strVal = std::to_string( v.second.nVal );
362 ASSERT_TRUE( updResult.first );
363 ASSERT_FALSE( updResult.second );
366 updResult = m.update( i, []( bool, map_pair& ) {
367 EXPECT_TRUE( false );
369 ASSERT_FALSE( updResult.first );
370 ASSERT_FALSE( updResult.second );
372 updResult = m.update( i, []( bool bNew, map_pair& v ) {
374 v.second.nVal = v.first.nKey;
376 ASSERT_TRUE( updResult.first );
377 ASSERT_TRUE( updResult.second );
379 updResult = m.update( i, []( bool bNew, map_pair& v ) {
380 EXPECT_FALSE( bNew );
381 EXPECT_EQ( v.first.nKey, v.second.nVal );
382 v.second.strVal = std::to_string( v.second.nVal );
384 ASSERT_TRUE( updResult.first );
385 ASSERT_FALSE( updResult.second );
388 updResult = m.update( val.strVal, []( bool, map_pair& ) {
389 EXPECT_TRUE( false );
391 ASSERT_FALSE( updResult.first );
392 ASSERT_FALSE( updResult.second );
394 updResult = m.update( val.strVal, []( bool bNew, map_pair& v ) {
396 v.second.nVal = v.first.nKey;
398 ASSERT_TRUE( updResult.first );
399 ASSERT_TRUE( updResult.second );
401 updResult = m.update( val.strVal, []( bool bNew, map_pair& v ) {
402 EXPECT_FALSE( bNew );
403 EXPECT_EQ( v.first.nKey, v.second.nVal );
404 v.second.strVal = std::to_string( v.second.nVal );
406 ASSERT_TRUE( updResult.first );
407 ASSERT_FALSE( updResult.second );
410 ASSERT_TRUE( m.emplace( i.nKey ));
411 ASSERT_FALSE( m.emplace( i.nKey ));
412 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
413 v.second.nVal = v.first.nKey;
414 v.second.strVal = std::to_string( v.first.nKey );
418 ASSERT_TRUE( m.emplace( i, i.nKey ));
419 ASSERT_FALSE( m.emplace( i, i.nKey ));
423 std::string str = val.strVal;
424 ASSERT_TRUE( m.emplace( i, std::move( str )));
425 ASSERT_TRUE( str.empty());
427 ASSERT_FALSE( m.emplace( i, std::move( str )));
428 ASSERT_TRUE( str.empty());
433 std::string str = val.strVal;
434 ASSERT_TRUE( m.emplace( i, i.nKey, std::move( str )));
435 ASSERT_TRUE( str.empty());
437 ASSERT_FALSE( m.emplace( i, i.nKey, std::move( str )));
438 ASSERT_TRUE( str.empty());
443 ASSERT_TRUE( m.contains( i.nKey ));
444 ASSERT_TRUE( m.contains( i ));
445 ASSERT_TRUE( m.contains( other_item( i.nKey ), other_less()));
446 ASSERT_TRUE( m.find( i, []( map_pair const& v ) {
447 EXPECT_EQ( v.first.nKey, v.second.nVal );
448 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
450 ASSERT_TRUE( m.find( i.nKey, []( map_pair const& v ) {
451 EXPECT_EQ( v.first.nKey, v.second.nVal );
452 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
454 ASSERT_TRUE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& v ) {
455 EXPECT_EQ( v.first.nKey, v.second.nVal );
456 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
459 ASSERT_FALSE( m.empty() );
460 ASSERT_CONTAINER_SIZE( m, kkSize );
461 ASSERT_FALSE( m.begin() == m.end() );
462 ASSERT_FALSE( m.cbegin() == m.cend() );
464 shuffle( arrKeys.begin(), arrKeys.end() );
467 for ( auto const& i : arrKeys ) {
468 value_type const& val( arrVals.at( i.nKey ) );
470 ASSERT_TRUE( m.contains( i.nKey ));
471 ASSERT_TRUE( m.contains( val.strVal ) );
472 ASSERT_TRUE( m.contains( i ));
473 ASSERT_TRUE( m.contains( other_item( i.nKey ), other_less()));
474 ASSERT_TRUE( m.find( i, []( map_pair const& v ) {
475 EXPECT_EQ( v.first.nKey, v.second.nVal );
476 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
478 ASSERT_TRUE( m.find( i.nKey, []( map_pair const& v ) {
479 EXPECT_EQ( v.first.nKey, v.second.nVal );
480 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
482 ASSERT_TRUE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& v ) {
483 EXPECT_EQ( v.first.nKey, v.second.nVal );
484 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
488 switch ( i.nKey % 8 ) {
490 ASSERT_TRUE( m.erase( i ));
491 ASSERT_FALSE( m.erase( i ));
494 ASSERT_TRUE( m.erase( i.nKey ));
495 ASSERT_FALSE( m.erase( i.nKey ));
498 ASSERT_TRUE( m.erase( val.strVal ));
499 ASSERT_FALSE( m.erase( val.strVal ));
502 ASSERT_TRUE( m.erase_with( other_item( i.nKey ), other_less()));
503 ASSERT_FALSE( m.erase_with( other_item( i.nKey ), other_less()));
506 ASSERT_TRUE( m.erase( i, []( map_pair& v ) {
507 EXPECT_EQ( v.first.nKey, v.second.nVal );
508 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
510 ASSERT_FALSE( m.erase( i, []( map_pair& ) {
511 EXPECT_TRUE( false );
515 ASSERT_TRUE( m.erase( i.nKey, []( map_pair& v ) {
516 EXPECT_EQ( v.first.nKey, v.second.nVal );
517 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
519 ASSERT_FALSE( m.erase( i.nKey, []( map_pair& ) {
520 EXPECT_TRUE( false );
524 ASSERT_TRUE( m.erase( val.strVal, []( map_pair& v ) {
525 EXPECT_EQ( v.first.nKey, v.second.nVal );
526 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
528 ASSERT_FALSE( m.erase( val.strVal, []( map_pair& ) {
529 EXPECT_TRUE( false );
533 ASSERT_TRUE( m.erase_with( other_item( i.nKey ), other_less(), []( map_pair& v ) {
534 EXPECT_EQ( v.first.nKey, v.second.nVal );
535 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
537 ASSERT_FALSE( m.erase_with( other_item( i.nKey ), other_less(), []( map_pair& ) {
538 EXPECT_TRUE( false );
543 ASSERT_FALSE( m.contains( i.nKey ));
544 ASSERT_FALSE( m.contains( i ));
545 ASSERT_FALSE( m.contains( val.strVal ));
546 ASSERT_FALSE( m.contains( other_item( i.nKey ), other_less()));
547 ASSERT_FALSE( m.find( i, []( map_pair const& ) {
548 ASSERT_TRUE( false );
550 ASSERT_FALSE( m.find( i.nKey, []( map_pair const& ) {
551 EXPECT_TRUE( false );
553 ASSERT_FALSE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& ) {
554 EXPECT_TRUE( false );
557 ASSERT_TRUE( m.empty() );
558 ASSERT_CONTAINER_SIZE( m, 0 );
560 ASSERT_TRUE( m.begin() == m.end());
561 ASSERT_TRUE( m.cbegin() == m.cend());
564 for ( auto const& i : arrKeys )
565 ASSERT_TRUE( m.insert( i ));
567 ASSERT_FALSE( m.empty() );
568 ASSERT_CONTAINER_SIZE( m, kkSize );
572 ASSERT_TRUE( m.empty() );
573 ASSERT_CONTAINER_SIZE( m, 0 );
577 } // namespace cds_test
579 #endif // #ifndef CDSUNIT_MAP_TEST_MAP_H