Home | History | Annotate | Download | only in unit
      1 #include <vector>
      2 #include <algorithm>
      3 #include <string>
      4 #if defined (STLPORT)
      5 #  include <unordered_map>
      6 #  include <unordered_set>
      7 #endif
      8 
      9 //#include <iostream>
     10 
     11 #include "cppunit/cppunit_proxy.h"
     12 
     13 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     14 using namespace std;
     15 #  if defined (STLPORT)
     16 using namespace std::tr1;
     17 #  endif
     18 #endif
     19 
     20 //
     21 // TestCase class
     22 //
     23 class UnorderedTest : public CPPUNIT_NS::TestCase
     24 {
     25   CPPUNIT_TEST_SUITE(UnorderedTest);
     26 #if !defined (STLPORT)
     27   CPPUNIT_IGNORE;
     28 #endif
     29   CPPUNIT_TEST(uset);
     30   CPPUNIT_TEST(umultiset);
     31   CPPUNIT_TEST(umap);
     32   CPPUNIT_TEST(umultimap);
     33   CPPUNIT_TEST(user_case);
     34   CPPUNIT_TEST(hash_policy);
     35   CPPUNIT_TEST(buckets);
     36   CPPUNIT_TEST(equal_range);
     37   CPPUNIT_EXPLICIT_TEST(benchmark1);
     38   CPPUNIT_EXPLICIT_TEST(benchmark2);
     39 #if !defined (_STLP_USE_CONTAINERS_EXTENSION)
     40   CPPUNIT_IGNORE;
     41 #endif
     42   CPPUNIT_TEST(template_methods);
     43   CPPUNIT_TEST_SUITE_END();
     44 
     45 protected:
     46   void uset();
     47   void umultiset();
     48   void umap();
     49   void umultimap();
     50   void user_case();
     51   void hash_policy();
     52   void buckets();
     53   void equal_range();
     54   void benchmark1();
     55   void benchmark2();
     56   void template_methods();
     57 };
     58 
     59 CPPUNIT_TEST_SUITE_REGISTRATION(UnorderedTest);
     60 
     61 const int NB_ELEMS = 2000;
     62 
     63 //
     64 // tests implementation
     65 //
     66 void UnorderedTest::uset()
     67 {
     68 #if defined (STLPORT)
     69   typedef unordered_set<int, hash<int>, equal_to<int> > usettype;
     70   usettype us;
     71 
     72   //Small compilation check of the copy constructor:
     73   usettype us2(us);
     74   //And assignment operator
     75   us = us2;
     76 
     77   int i;
     78   pair<usettype::iterator, bool> ret;
     79   for (i = 0; i < NB_ELEMS; ++i) {
     80     ret = us.insert(i);
     81     CPPUNIT_ASSERT( ret.second );
     82     CPPUNIT_ASSERT( *ret.first == i );
     83 
     84     ret = us.insert(i);
     85     CPPUNIT_ASSERT( !ret.second );
     86     CPPUNIT_ASSERT( *ret.first == i );
     87   }
     88 
     89   vector<int> us_val;
     90 
     91   usettype::local_iterator lit, litEnd;
     92   for (i = 0; i < NB_ELEMS; ++i) {
     93     lit = us.begin(us.bucket(i));
     94     litEnd = us.end(us.bucket(i));
     95 
     96     usettype::size_type bucket_pos = us.bucket(*lit);
     97     for (; lit != litEnd; ++lit) {
     98       CPPUNIT_ASSERT( us.bucket(*lit) == bucket_pos );
     99       us_val.push_back(*lit);
    100     }
    101   }
    102 
    103   //A compilation time check to uncomment from time to time
    104   {
    105     //usettype::iterator it;
    106     //CPPUNIT_ASSERT( it != lit );
    107   }
    108 
    109   sort(us_val.begin(), us_val.end());
    110   for (i = 0; i < NB_ELEMS; ++i) {
    111     CPPUNIT_ASSERT( us_val[i] == i );
    112   }
    113 #endif
    114 }
    115 
    116 void UnorderedTest::umultiset()
    117 {
    118 #if defined (STLPORT)
    119   typedef unordered_multiset<int, hash<int>, equal_to<int> > usettype;
    120   usettype us;
    121 
    122   int i;
    123   usettype::iterator ret;
    124   for (i = 0; i < NB_ELEMS; ++i) {
    125     ret = us.insert(i);
    126     CPPUNIT_ASSERT( *ret == i );
    127 
    128     ret = us.insert(i);
    129     CPPUNIT_ASSERT( *ret == i );
    130   }
    131 
    132   CPPUNIT_ASSERT( us.size() == 2 * NB_ELEMS );
    133   vector<int> us_val;
    134 
    135   usettype::local_iterator lit, litEnd;
    136   for (i = 0; i < NB_ELEMS; ++i) {
    137     lit = us.begin(us.bucket(i));
    138     litEnd = us.end(us.bucket(i));
    139 
    140     usettype::size_type bucket_pos = us.bucket(*lit);
    141     for (; lit != litEnd; ++lit) {
    142       CPPUNIT_ASSERT( us.bucket(*lit) == bucket_pos );
    143       us_val.push_back(*lit);
    144     }
    145   }
    146 
    147   sort(us_val.begin(), us_val.end());
    148   for (i = 0; i < NB_ELEMS; ++i) {
    149     CPPUNIT_ASSERT( us_val[2 * i] == i );
    150     CPPUNIT_ASSERT( us_val[2 * i + 1] == i );
    151   }
    152 #endif
    153 }
    154 
    155 void UnorderedTest::umap()
    156 {
    157 #if defined (STLPORT)
    158   typedef unordered_map<int, int, hash<int>, equal_to<int> > umaptype;
    159   umaptype us;
    160 
    161   //Compilation check of the [] operator:
    162   umaptype us2;
    163   us[0] = us2[0];
    164   us.clear();
    165 
    166   {
    167     //An other compilation check
    168     typedef unordered_map<int, umaptype> uumaptype;
    169     uumaptype uus;
    170     umaptype const& uref = uus[0];
    171     umaptype ucopy = uus[0];
    172     ucopy = uref;
    173     //Avoids warning:
    174     //(void*)&uref;
    175   }
    176 
    177   int i;
    178   pair<umaptype::iterator, bool> ret;
    179   for (i = 0; i < NB_ELEMS; ++i) {
    180     umaptype::value_type p1(i, i);
    181     ret = us.insert(p1);
    182     CPPUNIT_ASSERT( ret.second );
    183     CPPUNIT_ASSERT( *ret.first == p1 );
    184 
    185     umaptype::value_type p2(i, i + 1);
    186     ret = us.insert(p2);
    187     CPPUNIT_ASSERT( !ret.second );
    188     CPPUNIT_ASSERT( *ret.first == p1 );
    189   }
    190 
    191   {
    192     //Lets look for some values to see if everything is normal:
    193     umaptype::iterator umit;
    194     for (int j = 0; j < NB_ELEMS; j += NB_ELEMS / 100) {
    195       umit = us.find(j);
    196 
    197       CPPUNIT_ASSERT( umit != us.end() );
    198       CPPUNIT_ASSERT( (*umit).second == j );
    199     }
    200   }
    201 
    202   CPPUNIT_ASSERT( us.size() == (size_t)NB_ELEMS );
    203   vector<pair<int, int> > us_val;
    204 
    205   umaptype::local_iterator lit, litEnd;
    206   for (i = 0; i < NB_ELEMS; ++i) {
    207     lit = us.begin(us.bucket(i));
    208     litEnd = us.end(us.bucket(i));
    209 
    210     umaptype::size_type bucket_pos = us.bucket((*lit).first);
    211     for (; lit != litEnd; ++lit) {
    212       CPPUNIT_ASSERT( us.bucket((*lit).first) == bucket_pos );
    213       us_val.push_back(make_pair((*lit).first, (*lit).second));
    214     }
    215   }
    216 
    217   sort(us_val.begin(), us_val.end());
    218   for (i = 0; i < NB_ELEMS; ++i) {
    219     CPPUNIT_ASSERT( us_val[i] == make_pair(i, i) );
    220   }
    221 #endif
    222 }
    223 
    224 void UnorderedTest::umultimap()
    225 {
    226 #if defined (STLPORT)
    227   typedef unordered_multimap<int, int, hash<int>, equal_to<int> > umaptype;
    228   umaptype us;
    229 
    230   int i;
    231   umaptype::iterator ret;
    232   for (i = 0; i < NB_ELEMS; ++i) {
    233     umaptype::value_type p(i, i);
    234     ret = us.insert(p);
    235     CPPUNIT_ASSERT( *ret == p );
    236 
    237     ret = us.insert(p);
    238     CPPUNIT_ASSERT( *ret == p );
    239   }
    240 
    241   CPPUNIT_ASSERT( us.size() == 2 * NB_ELEMS );
    242   typedef pair<int, int> ptype;
    243   vector<ptype> us_val;
    244 
    245   umaptype::local_iterator lit, litEnd;
    246   for (i = 0; i < NB_ELEMS; ++i) {
    247     lit = us.begin(us.bucket(i));
    248     litEnd = us.end(us.bucket(i));
    249 
    250     umaptype::size_type bucket_pos = us.bucket((*lit).first);
    251     for (; lit != litEnd; ++lit) {
    252       CPPUNIT_ASSERT( us.bucket((*lit).first) == bucket_pos );
    253       us_val.push_back(ptype((*lit).first, (*lit).second));
    254     }
    255   }
    256 
    257   sort(us_val.begin(), us_val.end());
    258   for (i = 0; i < NB_ELEMS; ++i) {
    259     ptype p(i, i);
    260     CPPUNIT_ASSERT( us_val[i * 2] == p );
    261     CPPUNIT_ASSERT( us_val[i * 2 + 1] == p );
    262   }
    263 #endif
    264 }
    265 
    266 void UnorderedTest::user_case()
    267 {
    268 #if defined (STLPORT)
    269   typedef unordered_map<int, string> UnorderedMap1;
    270   typedef unordered_map<int, UnorderedMap1> UnorderedMap2;
    271 
    272   UnorderedMap1 foo;
    273   UnorderedMap2 bar;
    274 
    275   foo.insert(UnorderedMap1::value_type(1, string("test1")));
    276   foo.insert(UnorderedMap1::value_type(2, string("test2")));
    277   foo.insert(UnorderedMap1::value_type(3, string("test3")));
    278   foo.insert(UnorderedMap1::value_type(4, string("test4")));
    279   foo.insert(UnorderedMap1::value_type(5, string("test5")));
    280 
    281   bar.insert(UnorderedMap2::value_type(0, foo));
    282   UnorderedMap2::iterator it = bar.find(0);
    283   CPPUNIT_ASSERT( it != bar.end() );
    284 
    285   UnorderedMap1 &body = it->second;
    286   UnorderedMap1::iterator cur = body.find(3);
    287   CPPUNIT_ASSERT( cur != body.end() );
    288 
    289   body.erase(body.begin(), body.end());
    290   CPPUNIT_ASSERT( body.empty() );
    291 #endif
    292 }
    293 
    294 void UnorderedTest::hash_policy()
    295 {
    296 #if defined (STLPORT)
    297   unordered_set<int> int_uset;
    298 
    299   CPPUNIT_ASSERT( int_uset.max_load_factor() == 1.0f );
    300   CPPUNIT_ASSERT( int_uset.load_factor() == 0.0f );
    301 
    302   size_t nbInserts = int_uset.bucket_count() - 1;
    303   for (int i = 0; (size_t)i < nbInserts; ++i) {
    304     int_uset.insert(i);
    305   }
    306   CPPUNIT_ASSERT( int_uset.size() == nbInserts );
    307 
    308   int_uset.max_load_factor(0.5f);
    309   int_uset.rehash(0);
    310   CPPUNIT_ASSERT( int_uset.load_factor() < int_uset.max_load_factor() );
    311 
    312   size_t bucketsHint = int_uset.bucket_count() + 1;
    313   int_uset.rehash(bucketsHint);
    314   CPPUNIT_ASSERT( int_uset.bucket_count() >= bucketsHint );
    315 
    316   CPPUNIT_ASSERT( int_uset.key_eq()(10, 10) );
    317   CPPUNIT_ASSERT( int_uset.hash_function()(10) == 10 );
    318 #endif
    319 }
    320 
    321 void UnorderedTest::buckets()
    322 {
    323 #if defined (STLPORT)
    324   unordered_set<int> int_uset;
    325 
    326   CPPUNIT_ASSERT( int_uset.bucket_count() < int_uset.max_bucket_count() );
    327 
    328   int i;
    329   size_t nbBuckets = int_uset.bucket_count();
    330   size_t nbInserts = int_uset.bucket_count() - 1;
    331   for (i = 0; (size_t)i < nbInserts; ++i) {
    332     int_uset.insert(i);
    333   }
    334   CPPUNIT_ASSERT( nbBuckets == int_uset.bucket_count() );
    335 
    336   size_t bucketSizes = 0;
    337   for (i = 0; (size_t)i < nbBuckets; ++i) {
    338     bucketSizes += int_uset.bucket_size(i);
    339   }
    340   CPPUNIT_ASSERT( bucketSizes == int_uset.size() );
    341 #endif
    342 }
    343 
    344 void UnorderedTest::equal_range()
    345 {
    346 #if defined (STLPORT)
    347   typedef unordered_multiset<size_t> umset;
    348   {
    349     //General test
    350     umset iumset;
    351     iumset.max_load_factor(10.0f);
    352 
    353     size_t nbBuckets = iumset.bucket_count();
    354 
    355     for (size_t i = 0; i < nbBuckets; ++i) {
    356       iumset.insert(i);
    357       iumset.insert(i + nbBuckets);
    358       iumset.insert(i + 2 * nbBuckets);
    359       iumset.insert(i + 3 * nbBuckets);
    360       iumset.insert(i + 4 * nbBuckets);
    361     }
    362 
    363     CPPUNIT_ASSERT( nbBuckets == iumset.bucket_count() );
    364     CPPUNIT_ASSERT( iumset.size() == 5 * nbBuckets );
    365 
    366     pair<umset::iterator, umset::iterator> p = iumset.equal_range(1);
    367     CPPUNIT_ASSERT( p.first != p.second );
    368 
    369     size_t nbElems = iumset.size();
    370     nbElems -= distance(p.first, p.second);
    371     for (umset::iterator j = p.first; j != p.second;) {
    372       iumset.erase(j++);
    373     }
    374 
    375     CPPUNIT_ASSERT( nbElems == iumset.size() );
    376 
    377     p = iumset.equal_range(2);
    378     CPPUNIT_ASSERT( p.first != p.second );
    379     nbElems -= distance(p.first, p.second);
    380     iumset.erase(p.first, p.second);
    381     CPPUNIT_ASSERT( nbElems == iumset.size() );
    382   }
    383 
    384   {
    385     //More specific test that tries to put many values in the same bucket
    386     umset iumset;
    387 
    388     size_t i;
    389     //We are going to add at least 20 values, to get a stable hash container while doing that
    390     //we force a large number of buckets:
    391     iumset.rehash(193);
    392 
    393     size_t nbBuckets = iumset.bucket_count();
    394     const size_t targetedBucket = nbBuckets / 2;
    395 
    396     //Lets put 10 values in the targeted bucket:
    397     for (i = 0; i < 10; ++i) {
    398       iumset.insert(targetedBucket + (i * nbBuckets));
    399     }
    400 
    401     //We put again 10 values in the targeted bucket and in reverse order:
    402     for (i = 9; i <= 10; --i) {
    403       iumset.insert(targetedBucket + (i * nbBuckets));
    404     }
    405 
    406     //Now we put some more elements until hash container is resized:
    407     i = 0;
    408     while (iumset.bucket_count() == nbBuckets) {
    409       iumset.insert(i++);
    410     }
    411 
    412     //CPPUNIT_ASSERT( iumset.bucket_size(targetedBucket) == 21 );
    413 
    414     pair<umset::iterator, umset::iterator> p = iumset.equal_range(targetedBucket);
    415     CPPUNIT_ASSERT( p.first != p.second );
    416     CPPUNIT_ASSERT( distance(p.first, p.second) == 3 );
    417 
    418     // Now we remove some elements until hash container is resized:
    419     nbBuckets = iumset.bucket_count();
    420     while (iumset.bucket_count() == nbBuckets &&
    421            !iumset.empty()) {
    422       iumset.erase(iumset.begin());
    423     }
    424     CPPUNIT_ASSERT( iumset.load_factor() <= iumset.max_load_factor() );
    425 
    426     // Adding an element back shouldn't change number of buckets:
    427     nbBuckets = iumset.bucket_count();
    428     iumset.insert(0);
    429     CPPUNIT_ASSERT( iumset.bucket_count() == nbBuckets );
    430   }
    431 
    432   {
    433     srand(0);
    434     for (int runs = 0; runs < 2; ++runs) {
    435       size_t magic = rand();
    436       umset hum;
    437       size_t c = 0;
    438       for (int i = 0; i < 10000; ++i) {
    439         if ((rand() % 500) == 0) {
    440           hum.insert(magic);
    441           ++c;
    442         }
    443         else {
    444           size_t r;
    445           while ((r = rand()) == magic)
    446             ;
    447           hum.insert(r);
    448         }
    449 
    450         /*
    451         if ((float)(hum.size() + 1) / (float)hum.bucket_count() > hum.max_load_factor()) {
    452           cout << "Hash container dump: Nb elems: " << hum.size() << ", Nb buckets: " << hum.bucket_count() << "\n";
    453           for (size_t b = 0; b < hum.bucket_count(); ++b) {
    454             if (hum.bucket_size(b) != 0) {
    455               umset::local_iterator litBegin(hum.begin(b)), litEnd(hum.end(b));
    456               cout << "B" << b << ": ";
    457               for (umset::local_iterator lit = litBegin; lit != litEnd; ++lit) {
    458                 if (lit != litBegin) {
    459                   cout << " - ";
    460                 }
    461                 cout << *lit;
    462               }
    463               cout << "\n";
    464             }
    465           }
    466           cout << endl;
    467         }
    468         */
    469       }
    470       CPPUNIT_ASSERT( hum.count(magic) == c );
    471     }
    472   }
    473 #endif
    474 }
    475 
    476 void UnorderedTest::benchmark1()
    477 {
    478 #if defined (STLPORT)
    479   typedef unordered_multiset<size_t> umset;
    480 
    481   const size_t target = 500000;
    482   umset iumset;
    483   iumset.max_load_factor(10);
    484   size_t i;
    485   for (i = 0; i < target; ++i) {
    486     iumset.insert(i);
    487   }
    488 
    489   for (i = 0; i < target; ++i) {
    490     iumset.erase(i);
    491   }
    492 #endif
    493 }
    494 
    495 void UnorderedTest::benchmark2()
    496 {
    497 #if defined (STLPORT)
    498   typedef unordered_multiset<size_t> umset;
    499 
    500   const size_t target = 500000;
    501   umset iumset;
    502   iumset.max_load_factor(10);
    503   size_t i;
    504   for (i = 0; i < target; ++i) {
    505     iumset.insert(target - i);
    506   }
    507 
    508   for (i = 0; i < target; ++i) {
    509     iumset.erase(target - i);
    510   }
    511 #endif
    512 }
    513 
    514 struct Key
    515 {
    516   Key() : m_data(0) {}
    517   explicit Key(int data) : m_data(data) {}
    518 
    519   int m_data;
    520 
    521 #if defined (__DMC__) // slist<_Tp,_Alloc>::remove error
    522   bool operator==(const Key&) const;
    523 #endif
    524 };
    525 
    526 struct KeyHash
    527 {
    528   size_t operator () (Key key) const
    529   { return (size_t)key.m_data; }
    530 
    531   size_t operator () (int data) const
    532   { return (size_t)data; }
    533 };
    534 
    535 struct KeyEqual
    536 {
    537   bool operator () (Key lhs, Key rhs) const
    538   { return lhs.m_data == rhs.m_data; }
    539 
    540   bool operator () (Key lhs, int rhs) const
    541   { return lhs.m_data == rhs; }
    542 
    543   bool operator () (int lhs, Key rhs) const
    544   { return lhs == rhs.m_data; }
    545 };
    546 
    547 struct KeyHashPtr
    548 {
    549   size_t operator () (Key const volatile *key) const
    550   { return (size_t)key->m_data; }
    551 
    552   size_t operator () (int data) const
    553   { return (size_t)data; }
    554 };
    555 
    556 struct KeyEqualPtr
    557 {
    558   bool operator () (Key const volatile *lhs, Key const volatile *rhs) const
    559   { return lhs->m_data == rhs->m_data; }
    560 
    561   bool operator () (Key const volatile *lhs, int rhs) const
    562   { return lhs->m_data == rhs; }
    563 
    564   bool operator () (int lhs, Key const volatile *rhs) const
    565   { return lhs == rhs->m_data; }
    566 };
    567 
    568 void UnorderedTest::template_methods()
    569 {
    570 #if defined (STLPORT) && defined (_STLP_USE_CONTAINERS_EXTENSION)
    571   {
    572     typedef unordered_set<Key, KeyHash, KeyEqual> Container;
    573     Container cont;
    574     cont.insert(Key(1));
    575     cont.insert(Key(2));
    576     cont.insert(Key(3));
    577     cont.insert(Key(4));
    578 
    579     CPPUNIT_ASSERT( cont.count(Key(1)) == 1 );
    580     CPPUNIT_ASSERT( cont.count(1) == 1 );
    581     CPPUNIT_ASSERT( cont.count(5) == 0 );
    582 
    583     CPPUNIT_ASSERT( cont.find(2) != cont.end() );
    584     CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) );
    585 
    586     Container const& ccont = cont;
    587     CPPUNIT_ASSERT( ccont.find(2) != ccont.end() );
    588     CPPUNIT_ASSERT( ccont.bucket(2) == ccont.bucket(2) );
    589     CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.begin(), ccont.end()) );
    590   }
    591 
    592   {
    593     typedef unordered_set<Key*, KeyHashPtr, KeyEqualPtr> Container;
    594     Container cont;
    595     Key key1(1), key2(2), key3(3), key4(4);
    596     cont.insert(&key1);
    597     cont.insert(&key2);
    598     cont.insert(&key3);
    599     cont.insert(&key4);
    600 
    601     CPPUNIT_ASSERT( cont.count(1) == 1 );
    602     CPPUNIT_ASSERT( cont.count(5) == 0 );
    603 
    604     CPPUNIT_ASSERT( cont.find(2) != cont.end() );
    605     CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) );
    606 
    607     Container const& ccont = cont;
    608     CPPUNIT_ASSERT( ccont.find(2) != ccont.end() );
    609     CPPUNIT_ASSERT( ccont.bucket(2) == ccont.bucket(2) );
    610     CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.begin(), ccont.end()) );
    611   }
    612   {
    613     typedef unordered_multiset<Key, KeyHash, KeyEqual> Container;
    614     Container cont;
    615     cont.insert(Key(1));
    616     cont.insert(Key(2));
    617     cont.insert(Key(1));
    618     cont.insert(Key(2));
    619 
    620     CPPUNIT_ASSERT( cont.count(Key(1)) == 2 );
    621     CPPUNIT_ASSERT( cont.count(1) == 2 );
    622     CPPUNIT_ASSERT( cont.count(5) == 0 );
    623 
    624     CPPUNIT_ASSERT( cont.find(2) != cont.end() );
    625     CPPUNIT_ASSERT( cont.equal_range(1) != make_pair(cont.end(), cont.end()) );
    626 
    627     Container const& ccont = cont;
    628     CPPUNIT_ASSERT( ccont.find(2) != ccont.end() );
    629     CPPUNIT_ASSERT( ccont.bucket(2) == ccont.bucket(2) );
    630     CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.end(), ccont.end()) );
    631   }
    632 
    633   {
    634     typedef unordered_multiset<Key const volatile*, KeyHashPtr, KeyEqualPtr> Container;
    635     Container cont;
    636     Key key1(1), key2(2), key3(3), key4(4);
    637     cont.insert(&key1);
    638     cont.insert(&key2);
    639     cont.insert(&key3);
    640     cont.insert(&key4);
    641 
    642     CPPUNIT_ASSERT( cont.count(1) == 1 );
    643     CPPUNIT_ASSERT( cont.count(5) == 0 );
    644 
    645     CPPUNIT_ASSERT( cont.find(2) != cont.end() );
    646     CPPUNIT_ASSERT( cont.equal_range(2) != make_pair(cont.begin(), cont.end()) );
    647 
    648     Container const& ccont = cont;
    649     CPPUNIT_ASSERT( ccont.find(2) != ccont.end() );
    650     CPPUNIT_ASSERT( ccont.bucket(2) == ccont.bucket(2) );
    651     CPPUNIT_ASSERT( ccont.equal_range(2) != make_pair(ccont.begin(), ccont.end()) );
    652   }
    653 #endif
    654 }
    655 
    656 #if defined (STLPORT) && \
    657     (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION))
    658 #  if !defined (__DMC__)
    659 /* Simple compilation test: Check that nested types like iterator
    660  * can be access even if type used to instanciate container is not
    661  * yet completely defined.
    662  */
    663 class IncompleteClass
    664 {
    665   unordered_set<IncompleteClass> usinstances;
    666   typedef unordered_set<IncompleteClass>::iterator usit;
    667   unordered_multiset<IncompleteClass> usminstances;
    668   typedef unordered_multiset<IncompleteClass>::iterator usmit;
    669 
    670   unordered_map<IncompleteClass, IncompleteClass> uminstances;
    671   typedef unordered_map<IncompleteClass, IncompleteClass>::iterator umit;
    672   unordered_multimap<IncompleteClass, IncompleteClass> umminstances;
    673   typedef unordered_multimap<IncompleteClass, IncompleteClass>::iterator ummit;
    674 };
    675 #  endif
    676 #endif
    677