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_algo.cpp
Go to the documentation of this file.
00001 /***********************************************************************************
00002   test_algo.cpp
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 #include "Tests.h"
00017 #include "LeakCheck.h"
00018 #include "SortClass.h"
00019 
00020 #if defined (EH_NEW_HEADERS)
00021 # include <algorithm>
00022 # include <cassert>
00023 #else
00024 # include <algo.h>
00025 # include <assert.h>
00026 #endif
00027 
00028 #if defined (EH_NEW_IOSTREAMS)
00029 # include <iostream>
00030 #else
00031 # include <iostream.h>
00032 #endif
00033 
00034 //
00035 // SortBuffer -- a buffer of SortClass objects that can be used to test sorting.
00036 //
00037 struct SortBuffer
00038 {
00039     enum { kBufferSize = 100 };
00040 
00041     SortClass* begin() { return items; }
00042     const SortClass* begin() const { return items; }
00043     SortClass* end() { return items + kBufferSize; }
00044     const SortClass* end() const { return items + kBufferSize; }
00045 
00046   // Sort each half of the buffer and reset the address of each element
00047   // so that merge() can be tested for stability.
00048     void PrepareMerge()
00049     {
00050         EH_STD::sort( begin(), begin() + ( end() - begin() )/2 );
00051         EH_STD::sort( begin() + ( end() - begin() )/2, end() );
00052         for ( SortClass* p = begin(); p != end(); p++ )
00053             p->ResetAddress();
00054     }
00055 
00056   SortBuffer()
00057   {
00058     PrepareMerge();
00059   }
00060 
00061   SortBuffer( const SortBuffer& rhs )
00062   {
00063     SortClass* q = begin();
00064     for ( const SortClass* p = rhs.begin() ; p != rhs.end(); p++,q++ )
00065       *q = *p;
00066   }
00067 
00068 private:
00069     SortClass items[kBufferSize];
00070 };
00071 
00072 //
00073 // less_by_reference -- a functor for comparing objects against a
00074 //   constant value.
00075 //
00076 template <class T>
00077 struct less_by_reference
00078 {
00079     less_by_reference( const T& arg ) : fArg(arg) {}
00080     bool operator()( const T& x ) const { return x < fArg; }
00081 private:
00082     const T& fArg;
00083 };
00084 
00085 struct test_stable_partition
00086 {
00087     test_stable_partition( const SortBuffer& buf )
00088         : orig( buf ), partitionPoint(SortClass::kRange / 2) {
00089         gTestController.SetCurrentTestName("stable_partition()");
00090         }
00091 
00092     void operator()( SortBuffer& buf ) const
00093     {
00094         less_by_reference<SortClass> throw_cmp( partitionPoint );
00095 
00096         SortClass* d = EH_STD::stable_partition( buf.begin(), buf.end(), throw_cmp );
00097 
00098         // Suppress warning about unused variable.
00099         d;
00100 
00101         // If we get here no exception occurred during the operation.
00102         // Stop any potential failures that might occur during verification.
00103         gTestController.CancelFailureCountdown();
00104 
00105         // Prepare an array of counts of the occurrence of each value in
00106         // the legal range.
00107         unsigned counts[SortClass::kRange];
00108         EH_STD::fill_n( counts, (int)SortClass::kRange, 0 );
00109         for ( const SortClass *q = orig.begin(); q != orig.end(); q++ )
00110             counts[ q->value() ]++;
00111 
00112         less_by_reference<TestClass> cmp( partitionPoint );
00113         for ( const SortClass* p = buf.begin(); p != buf.end(); p++ )
00114         {
00115           // Check that adjacent items with the same value haven't been
00116           // reordered. This could be a more thorough test.
00117             if ( p != buf.begin() && p->value() == p[-1].value() ) {
00118                 EH_ASSERT( p->GetAddress() > p[-1].GetAddress() );
00119             }
00120 
00121             // Check that the partitioning worked.
00122             EH_ASSERT( (p < d) == cmp( *p ) );
00123 
00124             // Decrement the appropriate count for each value.
00125             counts[ p->value() ]--;
00126         }
00127 
00128         // Check that the values were only rearranged, and none were lost.
00129         for ( unsigned j = 0; j < SortClass::kRange; j++ ) {
00130             EH_ASSERT( counts[j] == 0 );
00131         }
00132     }
00133 
00134 private:
00135     const SortBuffer& orig;
00136     SortClass partitionPoint;
00137 };
00138 
00139 void assert_sorted_version( const SortBuffer& orig, const SortBuffer& buf );
00140 
00141 /*===================================================================================
00142   assert_sorted_version
00143 
00144   EFFECTS: Asserts that buf is a stable-sorted version of orig.
00145 ====================================================================================*/
00146 void assert_sorted_version( const SortBuffer& orig, const SortBuffer& buf )
00147 {
00148   // Stop any potential failures that might occur during verification.
00149     gTestController.CancelFailureCountdown();
00150 
00151     // Prepare an array of counts of the occurrence of each value in
00152     // the legal range.
00153     unsigned counts[SortClass::kRange];
00154     EH_STD::fill_n( counts, (int)SortClass::kRange, 0 );
00155     for ( const SortClass *q = orig.begin(); q != orig.end(); q++ )
00156         counts[ q->value() ]++;
00157 
00158   // Check that each element is greater than the previous one, or if they are
00159   // equal, that their order has been preserved.
00160     for ( const SortClass* p = buf.begin(); p != buf.end(); p++ )
00161     {
00162         if ( p != buf.begin() ) {
00163             EH_ASSERT( p->value() > p[-1].value()
00164                     || p->value() == p[-1].value() && p->GetAddress() > p[-1].GetAddress() );
00165         }
00166     // Decrement the appropriate count for each value.
00167         counts[ p->value() ]--;
00168     }
00169 
00170   // Check that the values were only rearranged, and none were lost.
00171     for ( unsigned j = 0; j < SortClass::kRange; j++ ) {
00172         EH_ASSERT( counts[j] == 0 );
00173     }
00174 }
00175 
00176 //
00177 // The test operators
00178 //
00179 struct test_stable_sort_1
00180 {
00181     test_stable_sort_1( const SortBuffer& buf )
00182         : orig( buf ) {
00183         gTestController.SetCurrentTestName("stable_sort() #1");
00184         }
00185 
00186     void operator()( SortBuffer& buf ) const
00187     {
00188         EH_STD::stable_sort( buf.begin(), buf.end() );
00189         assert_sorted_version( orig, buf );
00190     }
00191 
00192 private:
00193     const SortBuffer& orig;
00194 };
00195 
00196 struct test_stable_sort_2
00197 {
00198     test_stable_sort_2( const SortBuffer& buf )
00199         : orig( buf ) {
00200             gTestController.SetCurrentTestName("stable_sort() #2");
00201         }
00202 
00203     void operator()( SortBuffer& buf ) const
00204     {
00205       EH_STD::stable_sort( buf.begin(), buf.end(), EH_STD::less<SortClass>() );
00206       assert_sorted_version( orig, buf );
00207     }
00208 
00209 private:
00210     const SortBuffer& orig;
00211 };
00212 
00213 struct test_inplace_merge_1
00214 {
00215     test_inplace_merge_1( SortBuffer& buf )
00216         : orig( buf ) {
00217         gTestController.SetCurrentTestName("inplace_merge #1()");
00218         }
00219 
00220     void operator()( SortBuffer& buf ) const
00221     {
00222         EH_STD::inplace_merge( buf.begin(), buf.begin() + ( buf.end() - buf.begin() )/2, buf.end() );
00223         assert_sorted_version( orig, buf );
00224     }
00225 
00226 private:
00227     const SortBuffer& orig;
00228 };
00229 
00230 struct test_inplace_merge_2
00231 {
00232     test_inplace_merge_2( SortBuffer& buf )
00233         : orig( buf ) {
00234         gTestController.SetCurrentTestName("inplace_merge() #2");
00235         }
00236 
00237     void operator()( SortBuffer& buf ) const
00238     {
00239         EH_STD::inplace_merge( buf.begin(), buf.begin() + ( buf.end() - buf.begin() )/2, buf.end(),
00240                        EH_STD::less<SortClass>() );
00241         assert_sorted_version( orig, buf );
00242     }
00243 
00244 private:
00245     const SortBuffer& orig;
00246 };
00247 
00248 void test_algo()
00249 {
00250     SortBuffer mergeBuf;
00251     mergeBuf.PrepareMerge();
00252 
00253     EH_STD::cerr<<"EH test : testing algo.h"<<EH_STD::endl;
00254     WeakCheck( mergeBuf, test_inplace_merge_1( mergeBuf ) );
00255     WeakCheck( mergeBuf, test_inplace_merge_2( mergeBuf ) );
00256 
00257     SortBuffer buf;
00258     WeakCheck( buf, test_stable_sort_1( buf ) );
00259     WeakCheck( buf, test_stable_sort_2( buf ) );
00260     WeakCheck( buf, test_stable_partition( buf ) );
00261 }

Generated on Sun May 27 2012 04:35:14 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.