Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentest_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
1.7.6.1
|