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 );
126 value_type& operator=( int i )
129 strVal = std::to_string( i );
133 value_type& operator=( std::string const& s )
135 nVal = std::stoi( s );
141 typedef std::pair<key_type const, value_type> pair_type;
145 bool operator ()( key_type const& v1, key_type const& v2 ) const
147 return v1.nKey < v2.nKey;
150 bool operator ()( key_type const& v1, int v2 ) const
155 bool operator ()( int v1, key_type const& v2 ) const
160 bool operator ()( key_type const& v1, std::string const& v2 ) const
162 return v1.nKey < std::stoi(v2 );
165 bool operator ()( std::string const& v1, key_type const& v2 ) const
167 return std::stoi( v1 ) < v2.nKey;
172 int operator ()( key_type const& v1, key_type const& v2 ) const
174 if ( v1.nKey < v2.nKey )
176 return v1.nKey > v2.nKey ? 1 : 0;
179 int operator ()( key_type const& v1, int v2 ) const
183 return v1.nKey > v2 ? 1 : 0;
186 int operator ()( int v1, key_type const& v2 ) const
190 return v1 > v2.nKey ? 1 : 0;
193 int operator ()( key_type const& v1, std::string const& v2 ) const
195 int n2 = std::stoi( v2 );
198 return v1.nKey > n2 ? 1 : 0;
201 int operator ()( std::string const& v1, key_type const& v2 ) const
203 int n1 = std::stoi( v1 );
206 return n1 > v2.nKey ? 1 : 0;
211 size_t operator()( int i ) const
213 return cds::opt::v::hash<int>()( i );
216 size_t operator()( std::string const& str ) const
218 return cds::opt::v::hash<int>()( std::stoi( str ));
221 template <typename T>
222 size_t operator()( T const& i ) const
224 return cds::opt::v::hash<int>()(i.nKey);
231 other_item( int key )
238 bool operator ()( key_type const& v1, other_item const& v2 ) const
240 return v1.nKey < v2.nKey;
242 bool operator ()( other_item const& v1, key_type const& v2 ) const
244 return v1.nKey < v2.nKey;
252 // Precondition: map is empty
253 // Postcondition: map is empty
255 ASSERT_TRUE( m.empty());
256 ASSERT_CONTAINER_SIZE( m, 0 );
258 typedef typename Map::value_type map_pair;
259 size_t const kkSize = kSize;
261 std::vector<key_type> arrKeys;
262 for ( int i = 0; i < static_cast<int>(kkSize); ++i )
263 arrKeys.push_back( key_type( i ));
264 shuffle( arrKeys.begin(), arrKeys.end());
266 std::vector< value_type > arrVals;
267 for ( size_t i = 0; i < kkSize; ++i ) {
269 val.nVal = static_cast<int>( i );
270 val.strVal = std::to_string( i );
271 arrVals.push_back( val );
275 for ( auto const& i : arrKeys ) {
276 value_type const& val( arrVals.at( i.nKey ));
278 ASSERT_FALSE( m.contains( i.nKey ));
279 ASSERT_FALSE( m.contains( i ));
280 ASSERT_FALSE( m.contains( other_item( i.nKey ), other_less()));
281 ASSERT_FALSE( m.find( i, []( map_pair const& ) {
282 ASSERT_TRUE( false );
284 ASSERT_FALSE( m.find( i.nKey, []( map_pair const& ) {
285 EXPECT_TRUE( false );
287 ASSERT_FALSE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& ) {
288 EXPECT_TRUE( false );
291 std::pair< bool, bool > updResult;
293 switch ( i.nKey % 16 ) {
295 ASSERT_TRUE( m.insert( i ));
296 ASSERT_FALSE( m.insert( i ));
297 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
298 v.second.nVal = v.first.nKey;
299 v.second.strVal = std::to_string( v.first.nKey );
303 ASSERT_TRUE( m.insert( i.nKey ));
304 ASSERT_FALSE( m.insert( i.nKey ));
305 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
306 v.second.nVal = v.first.nKey;
307 v.second.strVal = std::to_string( v.first.nKey );
311 ASSERT_TRUE( m.insert( std::to_string( i.nKey )));
312 ASSERT_FALSE( m.insert( std::to_string( i.nKey )));
313 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
314 v.second.nVal = v.first.nKey;
315 v.second.strVal = std::to_string( v.first.nKey );
319 ASSERT_TRUE( m.insert( i, val ));
320 ASSERT_FALSE( m.insert( i, val ));
323 ASSERT_TRUE( m.insert( i.nKey, val.strVal ));
324 ASSERT_FALSE( m.insert( i.nKey, val.strVal ));
327 ASSERT_TRUE( m.insert( val.strVal, i.nKey ));
328 ASSERT_FALSE( m.insert( val.strVal, i.nKey ));
331 ASSERT_TRUE( m.insert_with( i, []( map_pair& v ) {
332 v.second.nVal = v.first.nKey;
333 v.second.strVal = std::to_string( v.first.nKey );
335 ASSERT_FALSE( m.insert_with( i, []( map_pair& v ) {
336 EXPECT_TRUE( false );
340 ASSERT_TRUE( m.insert_with( i.nKey, []( map_pair& v ) {
341 v.second.nVal = v.first.nKey;
342 v.second.strVal = std::to_string( v.first.nKey );
344 ASSERT_FALSE( m.insert_with( i.nKey, []( map_pair& v ) {
345 EXPECT_TRUE( false );
349 ASSERT_TRUE( m.insert_with( val.strVal, []( map_pair& v ) {
350 v.second.nVal = v.first.nKey;
351 v.second.strVal = std::to_string( v.first.nKey );
353 ASSERT_FALSE( m.insert_with( val.strVal, []( map_pair& v ) {
354 EXPECT_TRUE( false );
358 updResult = m.update( i.nKey, []( bool, map_pair& ) {
359 EXPECT_TRUE( false );
361 ASSERT_FALSE( updResult.first );
362 ASSERT_FALSE( updResult.second );
364 updResult = m.update( i.nKey, []( bool bNew, map_pair& v ) {
366 v.second.nVal = v.first.nKey;
368 ASSERT_TRUE( updResult.first );
369 ASSERT_TRUE( updResult.second );
371 updResult = m.update( i.nKey, []( bool bNew, map_pair& v ) {
372 EXPECT_FALSE( bNew );
373 EXPECT_EQ( v.first.nKey, v.second.nVal );
374 v.second.strVal = std::to_string( v.second.nVal );
376 ASSERT_TRUE( updResult.first );
377 ASSERT_FALSE( updResult.second );
380 updResult = m.update( i, []( bool, map_pair& ) {
381 EXPECT_TRUE( false );
383 ASSERT_FALSE( updResult.first );
384 ASSERT_FALSE( updResult.second );
386 updResult = m.update( i, []( bool bNew, map_pair& v ) {
388 v.second.nVal = v.first.nKey;
390 ASSERT_TRUE( updResult.first );
391 ASSERT_TRUE( updResult.second );
393 updResult = m.update( i, []( bool bNew, map_pair& v ) {
394 EXPECT_FALSE( bNew );
395 EXPECT_EQ( v.first.nKey, v.second.nVal );
396 v.second.strVal = std::to_string( v.second.nVal );
398 ASSERT_TRUE( updResult.first );
399 ASSERT_FALSE( updResult.second );
402 updResult = m.update( val.strVal, []( bool, map_pair& ) {
403 EXPECT_TRUE( false );
405 ASSERT_FALSE( updResult.first );
406 ASSERT_FALSE( updResult.second );
408 updResult = m.update( val.strVal, []( bool bNew, map_pair& v ) {
410 v.second.nVal = v.first.nKey;
412 ASSERT_TRUE( updResult.first );
413 ASSERT_TRUE( updResult.second );
415 updResult = m.update( val.strVal, []( bool bNew, map_pair& v ) {
416 EXPECT_FALSE( bNew );
417 EXPECT_EQ( v.first.nKey, v.second.nVal );
418 v.second.strVal = std::to_string( v.second.nVal );
420 ASSERT_TRUE( updResult.first );
421 ASSERT_FALSE( updResult.second );
424 ASSERT_TRUE( m.emplace( i.nKey ));
425 ASSERT_FALSE( m.emplace( i.nKey ));
426 ASSERT_TRUE( m.find( i.nKey, []( map_pair& v ) {
427 v.second.nVal = v.first.nKey;
428 v.second.strVal = std::to_string( v.first.nKey );
432 ASSERT_TRUE( m.emplace( i, i.nKey ));
433 ASSERT_FALSE( m.emplace( i, i.nKey ));
437 std::string str = val.strVal;
438 ASSERT_TRUE( m.emplace( i, std::move( str )));
439 ASSERT_TRUE( str.empty());
441 ASSERT_FALSE( m.emplace( i, std::move( str )));
442 ASSERT_TRUE( str.empty());
447 std::string str = val.strVal;
448 ASSERT_TRUE( m.emplace( i, i.nKey, std::move( str )));
449 ASSERT_TRUE( str.empty());
451 ASSERT_FALSE( m.emplace( i, i.nKey, std::move( str )));
452 ASSERT_TRUE( str.empty());
457 ASSERT_TRUE( m.contains( i.nKey ));
458 ASSERT_TRUE( m.contains( i ));
459 ASSERT_TRUE( m.contains( other_item( i.nKey ), other_less()));
460 ASSERT_TRUE( m.find( i, []( map_pair const& v ) {
461 EXPECT_EQ( v.first.nKey, v.second.nVal );
462 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
464 ASSERT_TRUE( m.find( i.nKey, []( map_pair const& v ) {
465 EXPECT_EQ( v.first.nKey, v.second.nVal );
466 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
468 ASSERT_TRUE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& v ) {
469 EXPECT_EQ( v.first.nKey, v.second.nVal );
470 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
473 ASSERT_FALSE( m.empty() );
474 ASSERT_CONTAINER_SIZE( m, kkSize );
475 ASSERT_FALSE( m.begin() == m.end() );
476 ASSERT_FALSE( m.cbegin() == m.cend() );
478 shuffle( arrKeys.begin(), arrKeys.end() );
481 for ( auto const& i : arrKeys ) {
482 value_type const& val( arrVals.at( i.nKey ) );
484 ASSERT_TRUE( m.contains( i.nKey ));
485 ASSERT_TRUE( m.contains( val.strVal ) );
486 ASSERT_TRUE( m.contains( i ));
487 ASSERT_TRUE( m.contains( other_item( i.nKey ), other_less()));
488 ASSERT_TRUE( m.find( i, []( map_pair const& v ) {
489 EXPECT_EQ( v.first.nKey, v.second.nVal );
490 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
492 ASSERT_TRUE( m.find( i.nKey, []( map_pair const& v ) {
493 EXPECT_EQ( v.first.nKey, v.second.nVal );
494 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
496 ASSERT_TRUE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& v ) {
497 EXPECT_EQ( v.first.nKey, v.second.nVal );
498 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
502 switch ( i.nKey % 8 ) {
504 ASSERT_TRUE( m.erase( i ));
505 ASSERT_FALSE( m.erase( i ));
508 ASSERT_TRUE( m.erase( i.nKey ));
509 ASSERT_FALSE( m.erase( i.nKey ));
512 ASSERT_TRUE( m.erase( val.strVal ));
513 ASSERT_FALSE( m.erase( val.strVal ));
516 ASSERT_TRUE( m.erase_with( other_item( i.nKey ), other_less()));
517 ASSERT_FALSE( m.erase_with( other_item( i.nKey ), other_less()));
520 ASSERT_TRUE( m.erase( i, []( map_pair& v ) {
521 EXPECT_EQ( v.first.nKey, v.second.nVal );
522 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
524 ASSERT_FALSE( m.erase( i, []( map_pair& ) {
525 EXPECT_TRUE( false );
529 ASSERT_TRUE( m.erase( i.nKey, []( map_pair& v ) {
530 EXPECT_EQ( v.first.nKey, v.second.nVal );
531 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
533 ASSERT_FALSE( m.erase( i.nKey, []( map_pair& ) {
534 EXPECT_TRUE( false );
538 ASSERT_TRUE( m.erase( val.strVal, []( map_pair& v ) {
539 EXPECT_EQ( v.first.nKey, v.second.nVal );
540 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
542 ASSERT_FALSE( m.erase( val.strVal, []( map_pair& ) {
543 EXPECT_TRUE( false );
547 ASSERT_TRUE( m.erase_with( other_item( i.nKey ), other_less(), []( map_pair& v ) {
548 EXPECT_EQ( v.first.nKey, v.second.nVal );
549 EXPECT_EQ( std::to_string( v.first.nKey ), v.second.strVal );
551 ASSERT_FALSE( m.erase_with( other_item( i.nKey ), other_less(), []( map_pair& ) {
552 EXPECT_TRUE( false );
557 ASSERT_FALSE( m.contains( i.nKey ));
558 ASSERT_FALSE( m.contains( i ));
559 ASSERT_FALSE( m.contains( val.strVal ));
560 ASSERT_FALSE( m.contains( other_item( i.nKey ), other_less()));
561 ASSERT_FALSE( m.find( i, []( map_pair const& ) {
562 ASSERT_TRUE( false );
564 ASSERT_FALSE( m.find( i.nKey, []( map_pair const& ) {
565 EXPECT_TRUE( false );
567 ASSERT_FALSE( m.find_with( other_item( i.nKey ), other_less(), []( map_pair const& ) {
568 EXPECT_TRUE( false );
571 ASSERT_TRUE( m.empty() );
572 ASSERT_CONTAINER_SIZE( m, 0 );
574 ASSERT_TRUE( m.begin() == m.end());
575 ASSERT_TRUE( m.cbegin() == m.cend());
578 for ( auto const& i : arrKeys )
579 ASSERT_TRUE( m.insert( i ));
581 ASSERT_FALSE( m.empty() );
582 ASSERT_CONTAINER_SIZE( m, kkSize );
586 ASSERT_TRUE( m.empty() );
587 ASSERT_CONTAINER_SIZE( m, 0 );
591 } // namespace cds_test
593 #endif // #ifndef CDSUNIT_MAP_TEST_MAP_H