ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

test_insert.h
Go to the documentation of this file.
00001 /***********************************************************************************
00002   test_insert.h
00003 
00004  * Copyright (c) 1997
00005  * Mark of the Unicorn, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute and sell this software
00008  * and its documentation for any purpose is hereby granted without fee,
00009  * provided that the above copyright notice appear in all copies and
00010  * that both that copyright notice and this permission notice appear
00011  * in supporting documentation.  Mark of the Unicorn makes no
00012  * representations about the suitability of this software for any
00013  * purpose.  It is provided "as is" without express or implied warranty.
00014 
00015 ***********************************************************************************/
00016 #ifndef test_insert_H_
00017 #define test_insert_H_
00018 
00019 # include "Prefix.h"
00020 # if defined (EH_NEW_HEADERS)
00021 #  include <utility>
00022 #  include <vector>
00023 #  include <cassert>
00024 #  include <climits>
00025 # else
00026 #  include <vector.h>
00027 #  include <assert.h>
00028 #  include <limits.h>
00029 # endif
00030 #include "random_number.h"
00031 #include "nc_alloc.h"
00032 #include "ThrowCompare.h"
00033 
00034 // A classification system for containers, for verification
00035 struct container_tag {};
00036 struct sequence_container_tag  {};
00037 struct associative_container_tag  {};
00038 
00039 struct set_tag  {};
00040 struct multiset_tag  {};
00041 struct map_tag {};
00042 struct multimap_tag {};
00043 
00044 template <class C, class Iter>
00045 size_t CountNewItems( const C&, const Iter& firstNew,
00046                       const Iter& lastNew, sequence_container_tag )
00047 {
00048     size_t dist = 0;
00049 #if 0 //def __SUNPRO_CC
00050     EH_DISTANCE( firstNew, lastNew, dist );
00051 #else
00052     EH_DISTANCE( Iter(firstNew), Iter(lastNew), dist );
00053 #endif
00054     return dist;
00055 }
00056 
00057 template <class C, class Iter>
00058 size_t CountNewItems( const C& c, const Iter& firstNew,
00059                       const Iter& lastNew, multimap_tag )
00060 {
00061     return CountNewItems( c, firstNew, lastNew, sequence_container_tag() );
00062 }
00063 
00064 template <class C, class Iter>
00065 size_t CountNewItems( const C& c, const Iter& firstNew,
00066                       const Iter& lastNew, multiset_tag )
00067 {
00068     return CountNewItems( c, firstNew, lastNew, sequence_container_tag() );
00069 }
00070 
00071 
00072 template <class C, class Iter, class KeyOfValue>
00073 #ifdef __BORLANDC__
00074 size_t CountUniqueItems_Aux( const C& original, const Iter& firstNew,
00075 #else
00076 size_t CountUniqueItems_Aux( const C& original, Iter firstNew,
00077 #endif
00078                              Iter lastNew, const KeyOfValue& keyOfValue )
00079 {
00080   typedef typename C::key_type key;
00081   typedef typename C::const_iterator const_iter;
00082   typedef EH_STD::vector<key> key_list;
00083   typedef typename key_list::iterator key_iterator;
00084   key_list keys;
00085   size_t dist = 0;
00086 #ifdef __SUNPRO_CC
00087   EH_DISTANCE( firstNew, lastNew, dist );
00088 #else
00089   EH_DISTANCE( Iter(firstNew), Iter(lastNew), dist );
00090 #endif
00091   keys.reserve( dist );
00092   for ( Iter x = firstNew; x != lastNew; ++x )
00093     keys.push_back( keyOfValue(*x) );
00094 
00095   EH_STD::sort( keys.begin(), keys.end() );
00096   key_iterator last = EH_STD::unique( keys.begin(), keys.end() );
00097 
00098     size_t cnt = 0;
00099     for ( key_iterator tmp = keys.begin(); tmp != last; ++tmp )
00100     {
00101         if ( const_iter(original.find( *tmp )) == const_iter(original.end()) )
00102             ++cnt;
00103     }
00104     return cnt;
00105 }
00106 
00107 #if ! defined (__SGI_STL)
00108 EH_BEGIN_NAMESPACE
00109 template <class T>
00110 struct identity
00111 {
00112   const T& operator()( const T& x ) const { return x; }
00113 };
00114 # if ! defined (__KCC)
00115 template <class _Pair>
00116 struct select1st : public unary_function<_Pair, typename _Pair::first_type> {
00117   const typename _Pair::first_type& operator()(const _Pair& __x) const {
00118     return __x.first;
00119   }
00120 };
00121 # endif
00122 EH_END_NAMESPACE
00123 #endif
00124 
00125 template <class C, class Iter>
00126 size_t CountUniqueItems( const C& original, const Iter& firstNew,
00127                          const Iter& lastNew, set_tag )
00128 {
00129     typedef typename C::value_type value_type;
00130     return CountUniqueItems_Aux( original, firstNew, lastNew,
00131                                  EH_STD::identity<value_type>() );
00132 }
00133 
00134 template <class C, class Iter>
00135 size_t CountUniqueItems( const C& original, const Iter& firstNew,
00136                          const Iter& lastNew, map_tag )
00137 {
00138 #ifdef EH_MULTI_CONST_TEMPLATE_ARG_BUG
00139     return CountUniqueItems_Aux( original, firstNew, lastNew,
00140                                  EH_SELECT1ST_HINT<C::value_type, C::key_type>() );
00141 #else
00142     typedef typename C::value_type value_type;
00143     return CountUniqueItems_Aux( original, firstNew, lastNew,
00144                                  EH_STD::select1st<value_type>() );
00145 #endif
00146 }
00147 
00148 template <class C, class Iter>
00149 size_t CountNewItems( const C& original, const Iter& firstNew,
00150                       const Iter& lastNew, map_tag )
00151 {
00152     return CountUniqueItems( original, firstNew, lastNew,
00153                              container_category( original ) );
00154 }
00155 
00156 template <class C, class Iter>
00157 size_t CountNewItems( const C& original, const Iter& firstNew,
00158                       const Iter& lastNew, set_tag )
00159 {
00160     return CountUniqueItems( original, firstNew, lastNew,
00161                              container_category( original ) );
00162 }
00163 
00164 template <class C, class SrcIter>
00165 inline void VerifyInsertion( const C& original, const C& result,
00166                              const SrcIter& firstNew, const SrcIter& lastNew,
00167                              size_t, associative_container_tag )
00168 {
00169     typedef typename C::const_iterator DstIter;
00170     DstIter first1 = original.begin();
00171     DstIter first2 = result.begin();
00172 
00173     DstIter* from_orig = new DstIter[original.size()];
00174     DstIter* last_from_orig = from_orig;
00175 
00176     // fbp : for hashed containers, the following is needed :
00177     while ( first2 != result.end() )
00178     {
00179         EH_STD::pair<DstIter, DstIter> p = EH_STD::mismatch( first1, original.end(), first2 );
00180         if ( p.second != result.end() )
00181         {
00182             SrcIter srcItem = EH_STD::find( SrcIter(firstNew), SrcIter(lastNew), *p.second );
00183 
00184             if (srcItem == lastNew)
00185             {
00186                 // not found in input range, probably re-ordered from the orig
00187                 DstIter* tmp;
00188                 tmp = EH_STD::find( from_orig, last_from_orig, p.first );
00189 
00190                 // if already here, exclude
00191                 if (tmp != last_from_orig)
00192                 {
00193                     EH_STD::copy(tmp+1, last_from_orig, tmp);
00194                     last_from_orig--;
00195                 }
00196                 else
00197                 {
00198                     // register re-ordered element
00199                     DstIter dstItem;
00200                     dstItem = EH_STD::find( first1, original.end(), *p.first );
00201                     EH_ASSERT( dstItem != original.end() );
00202                     *last_from_orig = dstItem;
00203                     last_from_orig++;
00204                     ++p.first;
00205                 }
00206             }
00207             ++p.second;
00208         }
00209         first1 = p.first;
00210         first2 = p.second;
00211     }
00212 
00213     delete [] from_orig;
00214 }
00215 
00216 // VC++
00217 template <class C, class SrcIter>
00218 inline void VerifyInsertion(
00219     const C& original, const C& result, const SrcIter& firstNew,
00220     const SrcIter& lastNew, size_t, set_tag )
00221 {
00222     VerifyInsertion( original, result, firstNew, lastNew,
00223                      size_t(0), associative_container_tag() );
00224 }
00225 
00226 template <class C, class SrcIter>
00227 inline void VerifyInsertion(const C& original, const C& result,
00228                             const SrcIter& firstNew, const SrcIter& lastNew,
00229                             size_t, multiset_tag )
00230 {
00231     VerifyInsertion( original, result, firstNew, lastNew,
00232                      size_t(0), associative_container_tag() );
00233 }
00234 
00235 template <class C, class SrcIter>
00236 inline void VerifyInsertion(
00237     const C& original, const C& result, const SrcIter& firstNew,
00238     const SrcIter& lastNew, size_t, map_tag )
00239 {
00240     VerifyInsertion( original, result, firstNew, lastNew,
00241                      size_t(0), associative_container_tag() );
00242 }
00243 
00244 template <class C, class SrcIter>
00245 inline void VerifyInsertion(
00246     const C& original, const C& result, const SrcIter& firstNew,
00247     const SrcIter& lastNew, size_t, multimap_tag )
00248 {
00249     VerifyInsertion( original, result, firstNew, lastNew,
00250                      size_t(0), associative_container_tag() );
00251 }
00252 
00253 template <class C, class SrcIter>
00254 void VerifyInsertion(
00255 # ifdef _MSC_VER
00256     const C& original, const C& result, SrcIter firstNew,
00257     SrcIter lastNew, size_t insPos, sequence_container_tag )
00258 # else
00259     const C& original, const C& result, const SrcIter& firstNew,
00260     const SrcIter& lastNew, size_t insPos, sequence_container_tag )
00261 # endif
00262 {
00263     typename C::const_iterator p1 = original.begin();
00264     typename C::const_iterator p2 = result.begin();
00265     SrcIter tmp(firstNew);
00266 
00267     for ( size_t n = 0; n < insPos; n++, ++p1, ++p2)
00268         EH_ASSERT( *p1 == *p2 );
00269 
00270     for (; tmp != lastNew; ++p2, ++tmp ) {
00271         EH_ASSERT(p2 != result.end());
00272         EH_ASSERT(*p2 == *tmp);
00273     }
00274 
00275     for (;  p2 != result.end(); ++p1, ++p2 )
00276         EH_ASSERT( *p1 == *p2 );
00277     EH_ASSERT( p1 == original.end() );
00278 }
00279 
00280 template <class C, class SrcIter>
00281 inline void VerifyInsertion( const C& original, const C& result,
00282                              const SrcIter& firstNew,
00283                              const SrcIter& lastNew, size_t insPos )
00284 {
00285     EH_ASSERT( result.size() == original.size() +
00286             CountNewItems( original, firstNew, lastNew,
00287                            container_category(original) ) );
00288     VerifyInsertion( original, result, firstNew, lastNew, insPos,
00289                      container_category(original) );
00290 }
00291 
00292 template <class C, class Value>
00293 void VerifyInsertN( const C& original, const C& result, size_t insCnt,
00294                     const Value& val, size_t insPos )
00295 {
00296     typename C::const_iterator p1 = original.begin();
00297     typename C::const_iterator p2 = result.begin();
00298   (void)val;    //*TY 02/06/2000 - to suppress unused variable warning under nondebug build
00299 
00300     for ( size_t n = 0; n < insPos; n++ )
00301         EH_ASSERT( *p1++ == *p2++ );
00302 
00303     while ( insCnt-- > 0 )
00304     {
00305         EH_ASSERT(p2 != result.end());
00306         EH_ASSERT(*p2 == val );
00307         ++p2;
00308     }
00309 
00310     while ( p2 != result.end() ) {
00311         EH_ASSERT( *p1 == *p2 );
00312         ++p1; ++p2;
00313     }
00314     EH_ASSERT( p1 == original.end() );
00315 }
00316 
00317 template <class C>
00318 void prepare_insert_n( C&, size_t ) {}
00319 
00320 // Metrowerks 1.8 compiler requires that specializations appear first (!!)
00321 // or it won't call them. Fixed in 1.9, though.
00322 inline void MakeRandomValue(bool& b) { b = bool(random_number(2) != 0); }
00323 
00324 template<class T>
00325 inline void MakeRandomValue(T&) {}
00326 
00327 template <class C>
00328 struct test_insert_one
00329 {
00330     test_insert_one( const C& orig, int pos =-1 )
00331         : original( orig ), fPos( random_number( orig.size() ))
00332     {
00333         MakeRandomValue( fInsVal );
00334         if ( pos != -1 )
00335         {
00336             fPos = size_t(pos);
00337             if ( pos == 0 )
00338                 gTestController.SetCurrentTestName("single insertion at begin()");
00339             else
00340                 gTestController.SetCurrentTestName("single insertion at end()");
00341         }
00342         else
00343             gTestController.SetCurrentTestName("single insertion at random position");
00344     }
00345 
00346     void operator()( C& c ) const
00347     {
00348         prepare_insert_n( c, (size_t)1 );
00349         typename C::iterator pos = c.begin();
00350         EH_STD::advance( pos, size_t(fPos) );
00351         c.insert( pos, fInsVal );
00352 
00353         // Prevent simulated failures during verification
00354         gTestController.CancelFailureCountdown();
00355         // Success. Check results.
00356         VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, fPos );
00357     }
00358 private:
00359     typename C::value_type fInsVal;
00360     const C& original;
00361     size_t fPos;
00362 };
00363 
00364 template <class C>
00365 struct test_insert_n
00366 {
00367     test_insert_n( const C& orig, size_t insCnt, int pos =-1 )
00368         : original( orig ), fPos( random_number( orig.size() )), fInsCnt(insCnt)
00369     {
00370         MakeRandomValue( fInsVal );
00371         if (pos!=-1)
00372         {
00373             fPos=size_t(pos);
00374             if (pos==0)
00375                 gTestController.SetCurrentTestName("n-ary insertion at begin()");
00376             else
00377                 gTestController.SetCurrentTestName("n-ary insertion at end()");
00378         }
00379         else
00380             gTestController.SetCurrentTestName("n-ary insertion at random position");
00381     }
00382 
00383     void operator()( C& c ) const
00384     {
00385         prepare_insert_n( c, fInsCnt );
00386         typename C::iterator pos = c.begin();
00387         EH_STD::advance( pos, fPos );
00388         c.insert( pos, fInsCnt, fInsVal );
00389 
00390         // Prevent simulated failures during verification
00391         gTestController.CancelFailureCountdown();
00392         // Success. Check results.
00393         VerifyInsertN( original, c, fInsCnt, fInsVal, fPos );
00394     }
00395 private:
00396     typename C::value_type fInsVal;
00397     const C& original;
00398     size_t fPos;
00399     size_t fInsCnt;
00400 };
00401 
00402 template <class C>
00403 struct test_insert_value
00404 {
00405     test_insert_value( const C& orig )
00406         : original( orig )
00407     {
00408         MakeRandomValue( fInsVal );
00409         gTestController.SetCurrentTestName("insertion of random value");
00410     }
00411 
00412     void operator()( C& c ) const
00413     {
00414         c.insert( fInsVal );
00415 
00416         // Prevent simulated failures during verification
00417         gTestController.CancelFailureCountdown();
00418         // Success. Check results.
00419         VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, size_t(0) );
00420     }
00421 private:
00422     typename C::value_type fInsVal;
00423     const C& original;
00424 };
00425 
00426 template <class C>
00427 struct test_insert_noresize
00428 {
00429     test_insert_noresize( const C& orig )
00430         : original( orig )
00431     {
00432         MakeRandomValue( fInsVal );
00433         gTestController.SetCurrentTestName("insertion of random value without resize");
00434     }
00435 
00436     void operator()( C& c ) const
00437     {
00438         c.insert_noresize( fInsVal );
00439 
00440         // Prevent simulated failures during verification
00441         gTestController.CancelFailureCountdown();
00442         // Success. Check results.
00443         VerifyInsertion( original, c, &fInsVal, 1+&fInsVal, size_t(0) );
00444     }
00445 private:
00446     typename C::value_type fInsVal;
00447     const C& original;
00448 };
00449 
00450 template <class C, class Position, class Iter>
00451 void do_insert_range( C& c_inst, Position offset,
00452                       Iter first, Iter last, sequence_container_tag )
00453 {
00454     typedef typename C::iterator CIter;
00455     CIter pos = c_inst.begin();
00456     EH_STD::advance( pos, offset );
00457     c_inst.insert( pos, first, last );
00458 }
00459 
00460 template <class C, class Position, class Iter>
00461 void do_insert_range( C& c, Position,
00462                       Iter first, Iter last, associative_container_tag )
00463 {
00464     c.insert( first, last );
00465 }
00466 
00467 template <class C, class Position, class Iter>
00468 void do_insert_range( C& c, Position, Iter first, Iter last, multiset_tag )
00469 {
00470     c.insert( first, last );
00471 }
00472 
00473 template <class C, class Position, class Iter>
00474 void do_insert_range( C& c, Position, Iter first, Iter last, multimap_tag )
00475 {
00476     c.insert( first, last );
00477 }
00478 
00479 template <class C, class Position, class Iter>
00480 void do_insert_range( C& c, Position, Iter first, Iter last, set_tag )
00481 {
00482     c.insert( first, last );
00483 }
00484 
00485 template <class C, class Position, class Iter>
00486 void do_insert_range( C& c, Position, Iter first, Iter last, map_tag )
00487 {
00488     c.insert( first, last );
00489 }
00490 
00491 /*
00492 template <class C, class Iter>
00493 void prepare_insert_range( C&, size_t, Iter, Iter) {}
00494 */
00495 
00496 template <class C, class Iter>
00497 struct test_insert_range
00498 {
00499     test_insert_range( const C& orig, Iter first, Iter last, int pos=-1 )
00500         : fFirst( first ),
00501           fLast( last ),
00502           original( orig ),
00503           fPos( random_number( orig.size() ))
00504     {
00505         gTestController.SetCurrentTestName("range insertion");
00506         if ( pos != -1 )
00507         {
00508             fPos = size_t(pos);
00509             if ( pos == 0 )
00510                 gTestController.SetCurrentTestName("range insertion at begin()");
00511             else
00512                 gTestController.SetCurrentTestName("range insertion at end()");
00513         }
00514         else
00515             gTestController.SetCurrentTestName("range insertion at random position");
00516     }
00517 
00518     void operator()( C& c ) const
00519     {
00520 //        prepare_insert_range( c, fPos, fFirst, fLast );
00521         do_insert_range( c, fPos, fFirst, fLast, container_category(c) );
00522 
00523         // Prevent simulated failures during verification
00524         gTestController.CancelFailureCountdown();
00525         // Success. Check results.
00526         VerifyInsertion( original, c, fFirst, fLast, fPos );
00527     }
00528 private:
00529     Iter fFirst, fLast;
00530     const C& original;
00531     size_t fPos;
00532 };
00533 
00534 template <class C, class Iter>
00535 test_insert_range<C, Iter> insert_range_tester( const C& orig, const Iter& first, const Iter& last )
00536 {
00537     return test_insert_range<C, Iter>( orig, first, last );
00538 }
00539 
00540 template <class C, class Iter>
00541 test_insert_range<C, Iter> insert_range_at_begin_tester( const C& orig, const Iter& first, const Iter& last )
00542 {
00543   return test_insert_range<C, Iter>( orig, first, last , 0);
00544 }
00545 
00546 template <class C, class Iter>
00547 test_insert_range<C, Iter> insert_range_at_end_tester( const C& orig, const Iter& first, const Iter& last )
00548 {
00549   return test_insert_range<C, Iter>( orig, first, last , (int)orig.size());
00550 }
00551 
00552 #endif // test_insert_H_

Generated on Sun May 27 2012 04:35:15 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.