Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenLeakCheck.h
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1997 00003 * Mark of the Unicorn, Inc. 00004 * 00005 * Permission to use, copy, modify, distribute and sell this software 00006 * and its documentation for any purpose is hereby granted without fee, 00007 * provided that the above copyright notice appear in all copies and 00008 * that both that copyright notice and this permission notice appear 00009 * in supporting documentation. Mark of the Unicorn makes no 00010 * representations about the suitability of this software for any 00011 * purpose. It is provided "as is" without express or implied warranty. 00012 */ 00013 /*********************************************************************************** 00014 LeakCheck.h 00015 00016 SUMMARY: A suite of template functions for verifying the behavior of 00017 operations in the presence of exceptions. Requires that the operations 00018 be written so that each operation that could cause an exception causes 00019 simulate_possible_failure() to be called (see "nc_alloc.h"). 00020 00021 ***********************************************************************************/ 00022 #ifndef INCLUDED_MOTU_LeakCheck 00023 #define INCLUDED_MOTU_LeakCheck 1 00024 00025 #include "Prefix.h" 00026 00027 #include "nc_alloc.h" 00028 00029 #include <cstdio> 00030 #include <cassert> 00031 #include <iterator> 00032 00033 #include <iostream> 00034 00035 EH_BEGIN_NAMESPACE 00036 00037 template <class T1, class T2> 00038 inline ostream& operator << ( 00039 ostream& s, 00040 const pair <T1, T2>& p) { 00041 return s<<'['<<p.first<<":"<<p.second<<']'; 00042 } 00043 EH_END_NAMESPACE 00044 00045 /*=================================================================================== 00046 CheckInvariant 00047 00048 EFFECTS: Generalized function to check an invariant on a container. Specialize 00049 this for particular containers if such a check is available. 00050 ====================================================================================*/ 00051 template <class C> 00052 void CheckInvariant(const C&) 00053 {} 00054 00055 /*=================================================================================== 00056 WeakCheck 00057 00058 EFFECTS: Given a value and an operation, repeatedly applies the operation to a 00059 copy of the value triggering the nth possible exception, where n increments 00060 with each repetition until no exception is thrown or max_iters is reached. 00061 Reports any detected memory leaks and checks any invariant defined for the 00062 value type whether the operation succeeds or fails. 00063 ====================================================================================*/ 00064 template <class Value, class Operation> 00065 void WeakCheck(const Value& v, const Operation& op, long max_iters = 2000000) { 00066 bool succeeded = false; 00067 bool failed = false; 00068 gTestController.SetCurrentTestCategory("weak"); 00069 for (long count = 0; !succeeded && !failed && count < max_iters; ++count) { 00070 gTestController.BeginLeakDetection(); 00071 { 00072 Value dup = v; 00073 #ifndef EH_NO_EXCEPTIONS 00074 try { 00075 #endif 00076 gTestController.SetFailureCountdown(count); 00077 op( dup ); 00078 succeeded = true; 00079 #ifndef EH_NO_EXCEPTIONS 00080 } 00081 catch (...) {} // Just try again. 00082 #endif 00083 gTestController.CancelFailureCountdown(); 00084 CheckInvariant(dup); 00085 } 00086 failed = gTestController.ReportLeaked(); 00087 EH_ASSERT( !failed ); 00088 00089 if ( succeeded ) 00090 gTestController.ReportSuccess(count); 00091 } 00092 EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over 00093 } 00094 00095 /*=================================================================================== 00096 ConstCheck 00097 00098 EFFECTS: Similar to WeakCheck (above), but for operations which may not modify 00099 their arguments. The operation is performed on the value itself, and no 00100 invariant checking is performed. Leak checking still occurs. 00101 ====================================================================================*/ 00102 template <class Value, class Operation> 00103 void ConstCheck(const Value& v, const Operation& op, long max_iters = 2000000) { 00104 bool succeeded = false; 00105 bool failed = false; 00106 gTestController.SetCurrentTestCategory("const"); 00107 for (long count = 0; !succeeded && !failed && count < max_iters; ++count) { 00108 gTestController.BeginLeakDetection(); 00109 { 00110 #ifndef EH_NO_EXCEPTIONS 00111 try { 00112 #endif 00113 gTestController.SetFailureCountdown(count); 00114 op( v ); 00115 succeeded = true; 00116 #ifndef EH_NO_EXCEPTIONS 00117 } 00118 catch(...) {} // Just try again. 00119 # endif 00120 gTestController.CancelFailureCountdown(); 00121 } 00122 failed = gTestController.ReportLeaked(); 00123 EH_ASSERT( !failed ); 00124 00125 if ( succeeded ) 00126 gTestController.ReportSuccess(count); 00127 } 00128 EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over 00129 } 00130 00131 /*=================================================================================== 00132 StrongCheck 00133 00134 EFFECTS: Similar to WeakCheck (above), but additionally checks a component of 00135 the "strong guarantee": if the operation fails due to an exception, the 00136 value being operated on must be unchanged, as checked with operator==(). 00137 00138 CAVEATS: Note that this does not check everything required for the strong 00139 guarantee, which says that if an exception is thrown, the operation has no 00140 effects. Do do that we would have to check that no there were no side-effects 00141 on objects which are not part of v (e.g. iterator validity must be preserved). 00142 00143 ====================================================================================*/ 00144 template <class Value, class Operation> 00145 void StrongCheck(const Value& v, const Operation& op, long max_iters = 2000000) { 00146 bool succeeded = false; 00147 bool failed = false; 00148 gTestController.SetCurrentTestCategory("strong"); 00149 for ( long count = 0; !succeeded && !failed && count < max_iters; count++ ) { 00150 gTestController.BeginLeakDetection(); 00151 00152 { 00153 Value dup = v; 00154 { 00155 #ifndef EH_NO_EXCEPTIONS 00156 try { 00157 #endif 00158 gTestController.SetFailureCountdown(count); 00159 op( dup ); 00160 succeeded = true; 00161 gTestController.CancelFailureCountdown(); 00162 # ifndef EH_NO_EXCEPTIONS 00163 } 00164 catch (...) { 00165 gTestController.CancelFailureCountdown(); 00166 bool unchanged = (dup == v); 00167 EH_ASSERT( unchanged ); 00168 00169 if ( !unchanged ) { 00170 #if 0 00171 typedef typename Value::value_type value_type; 00172 EH_STD::ostream_iterator<value_type> o(EH_STD::cerr, " "); 00173 EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n"; 00174 EH_STD::copy(dup.begin(), dup.end(), o); 00175 EH_STD::cerr<<"\nOriginal is:\n"; 00176 EH_STD::copy(v.begin(), v.end(), o); 00177 EH_STD::cerr<<EH_STD::endl; 00178 #endif 00179 failed = true; 00180 } 00181 } // Just try again. 00182 # endif 00183 CheckInvariant(v); 00184 } 00185 } 00186 00187 bool leaked = gTestController.ReportLeaked(); 00188 EH_ASSERT( !leaked ); 00189 if ( leaked ) 00190 failed = true; 00191 00192 if ( succeeded ) 00193 gTestController.ReportSuccess(count); 00194 } 00195 EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over 00196 } 00197 00198 #endif // INCLUDED_MOTU_LeakCheck Generated on Sat May 26 2012 04:34:04 for ReactOS by
1.7.6.1
|