1 //Has to be first for StackAllocator swap overload to be taken 2 //into account (at least using GCC 4.0.1) 3 #include "stack_allocator.h" 4 5 #include <map> 6 #include <algorithm> 7 8 #include "cppunit/cppunit_proxy.h" 9 10 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 11 using namespace std; 12 #endif 13 14 // 15 // TestCase class 16 // 17 class MapTest : public CPPUNIT_NS::TestCase 18 { 19 CPPUNIT_TEST_SUITE(MapTest); 20 CPPUNIT_TEST(map1); 21 CPPUNIT_TEST(mmap1); 22 CPPUNIT_TEST(mmap2); 23 CPPUNIT_TEST(iterators); 24 CPPUNIT_TEST(equal_range); 25 CPPUNIT_TEST(allocator_with_state); 26 #if !defined (STLPORT) || !defined (_STLP_USE_CONTAINERS_EXTENSION) 27 CPPUNIT_IGNORE; 28 #endif 29 CPPUNIT_TEST(template_methods); 30 CPPUNIT_TEST_SUITE_END(); 31 32 protected: 33 void map1(); 34 void mmap1(); 35 void mmap2(); 36 void iterators(); 37 void equal_range(); 38 void allocator_with_state(); 39 void template_methods(); 40 }; 41 42 CPPUNIT_TEST_SUITE_REGISTRATION(MapTest); 43 44 // 45 // tests implementation 46 // 47 void MapTest::map1() 48 { 49 typedef map<char, int, less<char> > maptype; 50 maptype m; 51 // Store mappings between roman numerals and decimals. 52 m['l'] = 50; 53 m['x'] = 20; // Deliberate mistake. 54 m['v'] = 5; 55 m['i'] = 1; 56 // cout << "m['x'] = " << m['x'] << endl; 57 CPPUNIT_ASSERT( m['x']== 20 ); 58 m['x'] = 10; // Correct mistake. 59 CPPUNIT_ASSERT( m['x']== 10 ); 60 CPPUNIT_ASSERT( m['z']== 0 ); 61 //cout << "m['z'] = " << m['z'] << endl; // Note default value is added. 62 CPPUNIT_ASSERT( m.count('z') == 1 ); 63 //cout << "m.count('z') = " << m.count('z') << endl; 64 pair<maptype::iterator, bool> p = m.insert(pair<const char, int>('c', 100)); 65 CPPUNIT_ASSERT( p.second ); 66 CPPUNIT_ASSERT( p.first != m.end() ); 67 CPPUNIT_ASSERT( (*p.first).first == 'c' ); 68 CPPUNIT_ASSERT( (*p.first).second == 100 ); 69 70 p = m.insert(pair<const char, int>('c', 100)); 71 CPPUNIT_ASSERT( !p.second ); // already existing pair 72 CPPUNIT_ASSERT( p.first != m.end() ); 73 CPPUNIT_ASSERT( (*p.first).first == 'c' ); 74 CPPUNIT_ASSERT( (*p.first).second == 100 ); 75 } 76 77 void MapTest::mmap1() 78 { 79 typedef multimap<char, int, less<char> > mmap; 80 mmap m; 81 CPPUNIT_ASSERT(m.count('X')==0); 82 83 m.insert(pair<const char, int>('X', 10)); // Standard way. 84 CPPUNIT_ASSERT(m.count('X')==1); 85 86 m.insert(pair<const char, int>('X', 20)); // jbuck: standard way 87 CPPUNIT_ASSERT(m.count('X')==2); 88 89 m.insert(pair<const char, int>('Y', 32)); // jbuck: standard way 90 mmap::iterator i = m.find('X'); // Find first match. 91 #ifndef _STLP_CONST 92 # define _STLP_CONST const 93 #endif 94 pair<_STLP_CONST char, int> p('X', 10); 95 CPPUNIT_ASSERT(*i == p); 96 CPPUNIT_ASSERT((*i).first == 'X'); 97 CPPUNIT_ASSERT((*i).second == 10); 98 i++; 99 CPPUNIT_ASSERT((*i).first == 'X'); 100 CPPUNIT_ASSERT((*i).second == 20); 101 i++; 102 CPPUNIT_ASSERT((*i).first == 'Y'); 103 CPPUNIT_ASSERT((*i).second == 32); 104 i++; 105 CPPUNIT_ASSERT(i == m.end()); 106 107 size_t count = m.erase('X'); 108 CPPUNIT_ASSERT(count==2); 109 } 110 void MapTest::mmap2() 111 { 112 typedef pair<const int, char> pair_type; 113 114 pair_type p1(3, 'c'); 115 pair_type p2(6, 'f'); 116 pair_type p3(1, 'a'); 117 pair_type p4(2, 'b'); 118 pair_type p5(3, 'x'); 119 pair_type p6(6, 'f'); 120 121 typedef multimap<int, char, less<int> > mmap; 122 123 pair_type array [] = { 124 p1, 125 p2, 126 p3, 127 p4, 128 p5, 129 p6 130 }; 131 132 mmap m(array + 0, array + 6); 133 mmap::iterator i; 134 i = m.lower_bound(3); 135 CPPUNIT_ASSERT((*i).first==3); 136 CPPUNIT_ASSERT((*i).second=='c'); 137 138 i = m.upper_bound(3); 139 CPPUNIT_ASSERT((*i).first==6); 140 CPPUNIT_ASSERT((*i).second=='f'); 141 } 142 143 144 void MapTest::iterators() 145 { 146 typedef map<int, char, less<int> > int_map; 147 int_map imap; 148 { 149 int_map::iterator ite(imap.begin()); 150 int_map::const_iterator cite(imap.begin()); 151 CPPUNIT_ASSERT( ite == cite ); 152 CPPUNIT_ASSERT( !(ite != cite) ); 153 CPPUNIT_ASSERT( cite == ite ); 154 CPPUNIT_ASSERT( !(cite != ite) ); 155 } 156 157 typedef multimap<int, char, less<int> > mmap; 158 typedef mmap::value_type pair_type; 159 160 pair_type p1(3, 'c'); 161 pair_type p2(6, 'f'); 162 pair_type p3(1, 'a'); 163 pair_type p4(2, 'b'); 164 pair_type p5(3, 'x'); 165 pair_type p6(6, 'f'); 166 167 pair_type array [] = { 168 p1, 169 p2, 170 p3, 171 p4, 172 p5, 173 p6 174 }; 175 176 mmap m(array+0, array + 6); 177 178 { 179 mmap::iterator ite(m.begin()); 180 mmap::const_iterator cite(m.begin()); 181 //test compare between const_iterator and iterator 182 CPPUNIT_ASSERT( ite == cite ); 183 CPPUNIT_ASSERT( !(ite != cite) ); 184 CPPUNIT_ASSERT( cite == ite ); 185 CPPUNIT_ASSERT( !(cite != ite) ); 186 } 187 188 #if 0 189 /* 190 * A check that map and multimap iterators are NOT comparable 191 * the following code should generate a compile time error 192 */ 193 { 194 int_map::iterator mite(imap.begin()); 195 int_map::const_iterator mcite(imap.begin()); 196 mmap::iterator mmite(m.begin()); 197 mmap::const_iterator mmcite(m.begin()); 198 CPPUNIT_ASSERT( !(mite == mmite) ); 199 CPPUNIT_ASSERT( !(mcite == mmcite) ); 200 CPPUNIT_ASSERT( mite != mmite ); 201 CPPUNIT_ASSERT( mcite != mmcite ); 202 CPPUNIT_ASSERT( !(mite == mmcite) ); 203 CPPUNIT_ASSERT( !(mite == mmcite) ); 204 CPPUNIT_ASSERT( mite != mmcite ); 205 CPPUNIT_ASSERT( mite != mmcite ); 206 } 207 208 #endif 209 210 mmap::reverse_iterator ri = m.rbegin(); 211 CPPUNIT_ASSERT( ri != m.rend() ); 212 CPPUNIT_ASSERT( ri == m.rbegin() ); 213 CPPUNIT_ASSERT( (*ri).first == 6 ); 214 CPPUNIT_ASSERT( (*ri++).second == 'f' ); 215 CPPUNIT_ASSERT( (*ri).first == 6 ); 216 CPPUNIT_ASSERT( (*ri).second == 'f' ); 217 218 mmap const& cm = m; 219 mmap::const_reverse_iterator rci = cm.rbegin(); 220 CPPUNIT_ASSERT( rci != cm.rend() ); 221 CPPUNIT_ASSERT( (*rci).first == 6 ); 222 CPPUNIT_ASSERT( (*rci++).second == 'f' ); 223 CPPUNIT_ASSERT( (*rci).first == 6 ); 224 CPPUNIT_ASSERT( (*rci).second == 'f' ); 225 } 226 227 void MapTest::equal_range() 228 { 229 typedef map<char, int, less<char> > maptype; 230 { 231 maptype m; 232 m['x'] = 10; 233 234 pair<maptype::iterator, maptype::iterator> ret; 235 ret = m.equal_range('x'); 236 CPPUNIT_ASSERT( ret.first != ret.second ); 237 CPPUNIT_ASSERT( (*(ret.first)).first == 'x' ); 238 CPPUNIT_ASSERT( (*(ret.first)).second == 10 ); 239 CPPUNIT_ASSERT( ++(ret.first) == ret.second ); 240 } 241 { 242 { 243 maptype m; 244 245 maptype::iterator i = m.lower_bound( 'x' ); 246 CPPUNIT_ASSERT( i == m.end() ); 247 248 i = m.upper_bound( 'x' ); 249 CPPUNIT_ASSERT( i == m.end() ); 250 251 pair<maptype::iterator, maptype::iterator> ret; 252 ret = m.equal_range('x'); 253 CPPUNIT_ASSERT( ret.first == ret.second ); 254 CPPUNIT_ASSERT( ret.first == m.end() ); 255 } 256 257 { 258 const maptype m; 259 pair<maptype::const_iterator, maptype::const_iterator> ret; 260 ret = m.equal_range('x'); 261 CPPUNIT_ASSERT( ret.first == ret.second ); 262 CPPUNIT_ASSERT( ret.first == m.end() ); 263 } 264 } 265 } 266 267 void MapTest::allocator_with_state() 268 { 269 char buf1[1024]; 270 StackAllocator<pair<const int, int> > stack1(buf1, buf1 + sizeof(buf1)); 271 272 char buf2[1024]; 273 StackAllocator<pair<const int, int> > stack2(buf2, buf2 + sizeof(buf2)); 274 275 { 276 typedef map<int, int, less<int>, StackAllocator<pair<const int, int> > > MapInt; 277 less<int> intLess; 278 MapInt mint1(intLess, stack1); 279 int i; 280 for (i = 0; i < 5; ++i) 281 mint1.insert(MapInt::value_type(i, i)); 282 MapInt mint1Cpy(mint1); 283 284 MapInt mint2(intLess, stack2); 285 for (; i < 10; ++i) 286 mint2.insert(MapInt::value_type(i, i)); 287 MapInt mint2Cpy(mint2); 288 289 mint1.swap(mint2); 290 291 CPPUNIT_ASSERT( mint1.get_allocator().swaped() ); 292 CPPUNIT_ASSERT( mint2.get_allocator().swaped() ); 293 294 CPPUNIT_ASSERT( mint1 == mint2Cpy ); 295 CPPUNIT_ASSERT( mint2 == mint1Cpy ); 296 CPPUNIT_ASSERT( mint1.get_allocator() == stack2 ); 297 CPPUNIT_ASSERT( mint2.get_allocator() == stack1 ); 298 } 299 CPPUNIT_ASSERT( stack1.ok() ); 300 CPPUNIT_ASSERT( stack2.ok() ); 301 } 302 303 struct Key 304 { 305 Key() : m_data(0) {} 306 explicit Key(int data) : m_data(data) {} 307 308 int m_data; 309 }; 310 311 struct KeyCmp 312 { 313 bool operator () (Key lhs, Key rhs) const 314 { return lhs.m_data < rhs.m_data; } 315 316 bool operator () (Key lhs, int rhs) const 317 { return lhs.m_data < rhs; } 318 319 bool operator () (int lhs, Key rhs) const 320 { return lhs < rhs.m_data; } 321 }; 322 323 struct KeyCmpPtr 324 { 325 bool operator () (Key const volatile *lhs, Key const volatile *rhs) const 326 { return (*lhs).m_data < (*rhs).m_data; } 327 328 bool operator () (Key const volatile *lhs, int rhs) const 329 { return (*lhs).m_data < rhs; } 330 331 bool operator () (int lhs, Key const volatile *rhs) const 332 { return lhs < (*rhs).m_data; } 333 }; 334 335 void MapTest::template_methods() 336 { 337 #if defined (STLPORT) && defined (_STLP_USE_CONTAINERS_EXTENSION) 338 { 339 typedef map<Key, int, KeyCmp> Container; 340 typedef Container::value_type value; 341 Container cont; 342 cont.insert(value(Key(1), 1)); 343 cont.insert(value(Key(2), 2)); 344 cont.insert(value(Key(3), 3)); 345 cont.insert(value(Key(4), 4)); 346 347 CPPUNIT_ASSERT( cont.count(Key(1)) == 1 ); 348 CPPUNIT_ASSERT( cont.count(1) == 1 ); 349 CPPUNIT_ASSERT( cont.count(5) == 0 ); 350 351 CPPUNIT_ASSERT( cont.find(2) != cont.end() ); 352 CPPUNIT_ASSERT( cont.lower_bound(2) != cont.end() ); 353 CPPUNIT_ASSERT( cont.upper_bound(2) != cont.end() ); 354 CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) ); 355 356 Container const& ccont = cont; 357 CPPUNIT_ASSERT( ccont.find(2) != ccont.end() ); 358 CPPUNIT_ASSERT( ccont.lower_bound(2) != ccont.end() ); 359 CPPUNIT_ASSERT( ccont.upper_bound(2) != ccont.end() ); 360 CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.end(), ccont.end()) ); 361 } 362 363 { 364 typedef map<Key*, int, KeyCmpPtr> Container; 365 typedef Container::value_type value; 366 Container cont; 367 Key key1(1), key2(2), key3(3), key4(4); 368 cont.insert(value(&key1, 1)); 369 cont.insert(value(&key2, 2)); 370 cont.insert(value(&key3, 3)); 371 cont.insert(value(&key4, 4)); 372 373 CPPUNIT_ASSERT( cont.count(1) == 1 ); 374 CPPUNIT_ASSERT( cont.count(5) == 0 ); 375 376 CPPUNIT_ASSERT( cont.find(2) != cont.end() ); 377 CPPUNIT_ASSERT( cont.lower_bound(2) != cont.end() ); 378 CPPUNIT_ASSERT( cont.upper_bound(2) != cont.end() ); 379 CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) ); 380 381 Container const& ccont = cont; 382 CPPUNIT_ASSERT( ccont.find(2) != ccont.end() ); 383 CPPUNIT_ASSERT( ccont.lower_bound(2) != ccont.end() ); 384 CPPUNIT_ASSERT( ccont.upper_bound(2) != ccont.end() ); 385 CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.begin(), ccont.end()) ); 386 } 387 { 388 typedef multimap<Key, int, KeyCmp> Container; 389 typedef Container::value_type value; 390 Container cont; 391 cont.insert(value(Key(1), 1)); 392 cont.insert(value(Key(2), 2)); 393 cont.insert(value(Key(3), 3)); 394 cont.insert(value(Key(4), 4)); 395 396 CPPUNIT_ASSERT( cont.count(Key(1)) == 1 ); 397 CPPUNIT_ASSERT( cont.count(1) == 1 ); 398 CPPUNIT_ASSERT( cont.count(5) == 0 ); 399 400 CPPUNIT_ASSERT( cont.find(2) != cont.end() ); 401 CPPUNIT_ASSERT( cont.lower_bound(2) != cont.end() ); 402 CPPUNIT_ASSERT( cont.upper_bound(2) != cont.end() ); 403 CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) ); 404 405 Container const& ccont = cont; 406 CPPUNIT_ASSERT( ccont.find(2) != ccont.end() ); 407 CPPUNIT_ASSERT( ccont.lower_bound(2) != ccont.end() ); 408 CPPUNIT_ASSERT( ccont.upper_bound(2) != ccont.end() ); 409 CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.end(), ccont.end()) ); 410 } 411 412 { 413 typedef multimap<Key const volatile*, int, KeyCmpPtr> Container; 414 typedef Container::value_type value; 415 Container cont; 416 Key key1(1), key2(2), key3(3), key4(4); 417 cont.insert(value(&key1, 1)); 418 cont.insert(value(&key2, 2)); 419 cont.insert(value(&key3, 3)); 420 cont.insert(value(&key4, 4)); 421 422 CPPUNIT_ASSERT( cont.count(1) == 1 ); 423 CPPUNIT_ASSERT( cont.count(5) == 0 ); 424 425 CPPUNIT_ASSERT( cont.find(2) != cont.end() ); 426 CPPUNIT_ASSERT( cont.lower_bound(2) != cont.end() ); 427 CPPUNIT_ASSERT( cont.upper_bound(2) != cont.end() ); 428 CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) ); 429 430 Container const& ccont = cont; 431 CPPUNIT_ASSERT( ccont.find(2) != ccont.end() ); 432 CPPUNIT_ASSERT( ccont.lower_bound(2) != ccont.end() ); 433 CPPUNIT_ASSERT( ccont.upper_bound(2) != ccont.end() ); 434 CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.begin(), ccont.end()) ); 435 } 436 #endif 437 } 438 439 #if !defined (STLPORT) || \ 440 !defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 441 # if !defined (__DMC__) 442 /* Simple compilation test: Check that nested types like iterator 443 * can be access even if type used to instanciate container is not 444 * yet completely defined. 445 */ 446 class IncompleteClass 447 { 448 map<IncompleteClass, IncompleteClass> instances; 449 typedef map<IncompleteClass, IncompleteClass>::iterator it; 450 multimap<IncompleteClass, IncompleteClass> minstances; 451 typedef multimap<IncompleteClass, IncompleteClass>::iterator mit; 452 }; 453 # endif 454 #endif 455