Simbody
|
00001 #ifndef SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 00002 #define SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2005-9 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00084 #include "SimTKcommon/internal/common.h" 00085 #include "SimTKcommon/internal/Exception.h" 00086 00087 #include <string> 00088 #include <iostream> 00089 #include <exception> 00090 00091 // --------------------------------- RANGECHECK -------------------------------- 00092 // These exceptions are to be used for situations in which a user of a SimTK 00093 // API method screws up by providing bad indices or dimensions. These are special 00094 // cases of the more general APIARGCHECK macros, providing "canned" error messages 00095 // for several common situations. Although there are several different macro 00096 // names here, all are controlled by SimTK_KEEP_RANGECHECK to allow enabling of 00097 // these index- and size-validating tests together in Release mode. 00098 // 00099 // INDEXCHECK: Note that we allow the index to be equal to the lower 00100 // bound (zero) but it must be strictly less than the upper bound. 00101 // SIZECHECK: A size or size expression must be >= 0 and less than OR EQUAL 00102 // to the maximum size. 00103 // SIZECHECK_NONNEG: A size argument must be >= 0. 00104 // VALUECHECK: A floating point is required to be within a certain range. 00105 // VALUECHECK_NONNEG: A floating point argument must be non-negative. 00106 // 00107 // TODO: SHAPECHECK, DOMAINCHECK 00108 // ----------------------------------------------------------------------------- 00109 00110 // This is a rangecheck that is always present, even in Release mode. This may be 00111 // applied both to signed and unsigned types (the latter are always nonnegative) so 00112 // to avoid warnings we use the isIndexInRange() method which doesn't perform 00113 // a nonnegativity check on unsigned quantities. 00114 #define SimTK_INDEXCHECK_ALWAYS(ix,ub,where) \ 00115 do{if(!isIndexInRange((ix),(ub)))SimTK_THROW5(SimTK::Exception::IndexOutOfRange, \ 00116 #ix,0,(ix),(ub),(where));}while(false) 00117 00118 // This is a rangecheck that is always present, even in Release mode. This may be 00119 // applied both to signed and unsigned types (the latter are always nonnegative) so 00120 // to avoid warnings we use the isSizeInRange() method which doesn't perform 00121 // a nonnegativity check on unsigned quantities. 00122 #define SimTK_SIZECHECK_ALWAYS(sz,maxsz,where) \ 00123 do{if(!isSizeInRange((sz),(maxsz)))SimTK_THROW4(SimTK::Exception::SizeOutOfRange, \ 00124 #sz,(sz),(maxsz),(where));}while(false) 00125 00126 // This is a rangecheck that is always present, even in Release mode. Use 00127 // isNonnegative() here in case sz is an unsigned type to avoid compiler 00128 // warning. 00129 #define SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where) \ 00130 do{if(!isNonnegative(sz))SimTK_THROW3(SimTK::Exception::SizeWasNegative, \ 00131 #sz,(sz),(where));}while(false) 00132 00133 // Similar checks for floating point values. 00134 00135 #define SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where) \ 00136 do{if(!(lb)<=(val)&&(val)<=(ub)))SimTK_THROW5(SimTK::Exception::ValueOutOfRange, \ 00137 (valName),(lb),(val),(ub),(where));}while(false) 00138 00139 00140 #define SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where) \ 00141 do{if((val)<0)SimTK_THROW3(SimTK::Exception::ValueWasNegative, \ 00142 (valName),(val),(where));}while(false) 00143 00144 00145 00146 #if defined(NDEBUG) && !defined(SimTK_KEEP_RANGECHECK) 00147 #define SimTK_INDEXCHECK(ix,ub,where) 00148 #define SimTK_SIZECHECK(sz,maxsz,where) 00149 #define SimTK_SIZECHECK_NONNEG(sz,where) 00150 #define SimTK_VALUECHECK(lb,val,ub,valName,where) 00151 #define SimTK_VALUECHECK_NONNEG(val,valName,where) 00152 #else 00153 #define SimTK_INDEXCHECK(ix,ub,where) SimTK_INDEXCHECK_ALWAYS(ix,ub,where) 00154 #define SimTK_SIZECHECK(sz,maxsz,where) SimTK_SIZECHECK_ALWAYS(sz,maxsz,where) 00155 #define SimTK_SIZECHECK_NONNEG(sz,where) SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where) 00156 #define SimTK_VALUECHECK(lb,val,ub,valName,where) SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where) 00157 #define SimTK_VALUECHECK_NONNEG(val,valName,where) SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where) 00158 #endif 00159 00160 00161 // --------------------------------- STAGECHECK -------------------------------- 00162 // These exceptions are to be used for situations in which a 00163 // user of an API screws up by attempting to access something in the 00164 // state before it has been realized to the appropriate stage. 00165 // 00166 // STAGECHECK_TOPOLOGY_REALIZED: Check that realizeTopology() has been done 00167 // since the last topological change. 00168 // STAGECHECK_EQ: Check that the current stage is == a particular stage. 00169 // STAGECHECK_GE: Check that the current stage is >= a particular stage. 00170 // STAGECHECK_LT: Check that the current stage is < a particular stage. 00171 // STAGECHECK_RANGE: Check that lower <= stage <= upper. 00172 // ----------------------------------------------------------------------------- 00173 00174 // These are stagechecks that is always present, even in Release mode. 00175 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodNm) \ 00176 do{if(!(cond)) SimTK_THROW3(SimTK::Exception::RealizeTopologyMustBeCalledFirst, \ 00177 (objType),(objName),(methodNm));}while(false) 00178 #define SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm) \ 00179 do{if((currentStage)!=(targetStage)) SimTK_THROW3(SimTK::Exception::StageIsWrong, \ 00180 (currentStage),(targetStage),(methodNm));}while(false) 00181 #define SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm) \ 00182 do{if(!((currentStage)>=(targetStage))) SimTK_THROW3(SimTK::Exception::StageTooLow, \ 00183 (currentStage),(targetStage),(methodNm));}while(false) 00184 #define SimTK_STAGECHECK_LT_ALWAYS(currentStage,targetStage,methodNm) \ 00185 do{if((currentStage)>=(targetStage)) SimTK_THROW3(SimTK::Exception::StageTooHigh, \ 00186 (currentStage),(targetStage),(methodNm));}while(false) 00187 #define SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm) \ 00188 do{if(!((lower)<=(current)&&(current)<=(upper))) SimTK_THROW4(SimTK::Exception::StageOutOfRange, \ 00189 (lower),(current),(upper),(methodNm));}while(false) 00190 00191 // This one is present only in Debug mode or if SimTK_KEEP_STAGECHECK is explicitly defined. 00192 #if defined(NDEBUG) && !defined(SimTK_KEEP_STAGECHECK) 00193 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED(cond,objType,objName,methodName) 00194 #define SimTK_STAGECHECK_EQ(currentStage,targetStage,methodNm) 00195 #define SimTK_STAGECHECK_GE(currentStage,targetStage,methodNm) 00196 #define SimTK_STAGECHECK_LT(currentStage,targetStage,methodNm) 00197 #define SimTK_STAGECHECK_RANGE(lower,current,upper,methodNm) 00198 #else 00199 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED(cond,objType,objName,methodName) \ 00200 SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodName) 00201 #define SimTK_STAGECHECK_EQ(currentStage,targetStage,methodNm) \ 00202 SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm) 00203 #define SimTK_STAGECHECK_GE(currentStage,targetStage,methodNm) \ 00204 SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm) 00205 #define SimTK_STAGECHECK_LT(currentStage,targetStage,methodNm) \ 00206 SimTK_STAGECHECK_LE_ALWAYS(currentStage,targetStage,methodNm) 00207 #define SimTK_STAGECHECK_RANGE(lower,current,upper,methodNm) \ 00208 SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm) 00209 #endif 00210 00211 // -------------------------------- APIARGCHECK -------------------------------- 00212 // These should be used to catch all manner of problems with the arguments passed 00213 // in an API user's call to a method that is part of a SimTK API. Note that these 00214 // are intended for direct consumption by an application programmer using a SimTK 00215 // API, so should be wordy and helpful. These macros accept printf-style format 00216 // strings and arguments of whatever are the appropriate types for those formats. 00217 // ----------------------------------------------------------------------------- 00218 00219 #define SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg) \ 00220 do{if(!(cond))SimTK_THROW4(SimTK::Exception::APIArgcheckFailed, \ 00221 #cond,(className),(methodName),(msg)); \ 00222 }while(false) 00223 #define SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1) \ 00224 do{if(!(cond))SimTK_THROW5(SimTK::Exception::APIArgcheckFailed, \ 00225 #cond,(className),(methodName),(fmt),(a1)); \ 00226 }while(false) 00227 #define SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2) \ 00228 do{if(!(cond))SimTK_THROW6(SimTK::Exception::APIArgcheckFailed, \ 00229 #cond,(className),(methodName),(fmt),(a1),(a2)); \ 00230 }while(false) 00231 #define SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3) \ 00232 do{if(!(cond))SimTK_THROW7(SimTK::Exception::APIArgcheckFailed, \ 00233 #cond,(className),(methodName),(fmt),(a1),(a2),(a3)); \ 00234 }while(false) 00235 #define SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4) \ 00236 do{if(!(cond))SimTK_THROW8(SimTK::Exception::APIArgcheckFailed, \ 00237 #cond,(className),(methodName),(fmt),(a1),(a2),(a3),(a4)); \ 00238 }while(false) 00239 #define SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5) \ 00240 do{if(!(cond))SimTK_THROW9(SimTK::Exception::APIArgcheckFailed, \ 00241 #cond,(className),(methodName),(fmt),(a1),(a2),(a3),(a4),(a5)); \ 00242 }while(false) 00243 00244 #if defined(NDEBUG) && !defined(SimTK_KEEP_APIARGCHECK) 00245 #define SimTK_APIARGCHECK(cond,className,methodName,msg) 00246 #define SimTK_APIARGCHECK1(cond,className,methodName,fmt,a1) 00247 #define SimTK_APIARGCHECK2(cond,className,methodName,fmt,a1,a2) 00248 #define SimTK_APIARGCHECK3(cond,className,methodName,fmt,a1,a2,a3) 00249 #define SimTK_APIARGCHECK4(cond,className,methodName,fmt,a1,a2,a3,a4) 00250 #define SimTK_APIARGCHECK5(cond,className,methodName,fmt,a1,a2,a3,a4,a5) 00251 #else 00252 #define SimTK_APIARGCHECK(cond,className,methodName,msg) \ 00253 SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg) 00254 #define SimTK_APIARGCHECK1(cond,className,methodName,fmt,a1) \ 00255 SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1) 00256 #define SimTK_APIARGCHECK2(cond,className,methodName,fmt,a1,a2) \ 00257 SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2) 00258 #define SimTK_APIARGCHECK3(cond,className,methodName,fmt,a1,a2,a3) \ 00259 SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3) 00260 #define SimTK_APIARGCHECK4(cond,className,methodName,fmt,a1,a2,a3,a4) \ 00261 SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4) 00262 #define SimTK_APIARGCHECK5(cond,className,methodName,fmt,a1,a2,a3,a4,a5) \ 00263 SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5) 00264 #endif 00265 00266 00267 // ----------------------------------- ERRCHK ---------------------------------- 00268 // ERRCHK: these should be used to catch all manner of problems that occur 00269 // during execution of an API user's request by a method that is part of 00270 // a SimTK API. Note that these are intended for direct consumption by 00271 // an application programmer using a SimTK API, so should be wordy and 00272 // helpful. These macros accept printf-style format strings and arguments 00273 // of whatever are the appropriate types for those formats. 00274 // ----------------------------------------------------------------------------- 00275 00276 #define SimTK_ERRCHK_ALWAYS(cond,whereChecked,msg) \ 00277 do{if(!(cond))SimTK_THROW3(SimTK::Exception::ErrorCheck, \ 00278 #cond,(whereChecked),(msg)); \ 00279 }while(false) 00280 #define SimTK_ERRCHK1_ALWAYS(cond,whereChecked,fmt,a1) \ 00281 do{if(!(cond))SimTK_THROW4(SimTK::Exception::ErrorCheck, \ 00282 #cond,(whereChecked),(fmt),(a1)); \ 00283 }while(false) 00284 #define SimTK_ERRCHK2_ALWAYS(cond,whereChecked,fmt,a1,a2) \ 00285 do{if(!(cond))SimTK_THROW5(SimTK::Exception::ErrorCheck, \ 00286 #cond,(whereChecked),(fmt),(a1),(a2)); \ 00287 }while(false) 00288 #define SimTK_ERRCHK3_ALWAYS(cond,whereChecked,fmt,a1,a2,a3) \ 00289 do{if(!(cond))SimTK_THROW6(SimTK::Exception::ErrorCheck, \ 00290 #cond,(whereChecked),(fmt),(a1),(a2),(a3)); \ 00291 }while(false) 00292 #define SimTK_ERRCHK4_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4) \ 00293 do{if(!(cond))SimTK_THROW7(SimTK::Exception::ErrorCheck, \ 00294 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4)); \ 00295 }while(false) 00296 #define SimTK_ERRCHK5_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5) \ 00297 do{if(!(cond))SimTK_THROW8(SimTK::Exception::ErrorCheck, \ 00298 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5)); \ 00299 }while(false) 00300 #define SimTK_ERRCHK6_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) \ 00301 do{if(!(cond))SimTK_THROW9(SimTK::Exception::ErrorCheck, \ 00302 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5),(a6)); \ 00303 }while(false) 00304 #define SimTK_ERRCHK7_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) \ 00305 do{if(!(cond))SimTK_THROW10(SimTK::Exception::ErrorCheck, \ 00306 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5),(a6),(a7)); \ 00307 }while(false) 00308 00309 #if defined(NDEBUG) && !defined(SimTK_KEEP_ERRCHK) 00310 #define SimTK_ERRCHK(cond,whereChecked,msg) 00311 #define SimTK_ERRCHK1(cond,whereChecked,fmt,a1) 00312 #define SimTK_ERRCHK2(cond,whereChecked,fmt,a1,a2) 00313 #define SimTK_ERRCHK3(cond,whereChecked,fmt,a1,a2,a3) 00314 #define SimTK_ERRCHK4(cond,whereChecked,fmt,a1,a2,a3,a4) 00315 #define SimTK_ERRCHK5(cond,whereChecked,fmt,a1,a2,a3,a4,a5) 00316 #define SimTK_ERRCHK6(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 00317 #define SimTK_ERRCHK7(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 00318 #else 00319 #define SimTK_ERRCHK(cond,whereChecked,msg) \ 00320 SimTK_ERRCHK_ALWAYS(cond,whereChecked,msg) 00321 #define SimTK_ERRCHK1(cond,whereChecked,fmt,a1) \ 00322 SimTK_ERRCHK1_ALWAYS(cond,whereChecked,fmt,a1) 00323 #define SimTK_ERRCHK2(cond,whereChecked,fmt,a1,a2) \ 00324 SimTK_ERRCHK2_ALWAYS(cond,whereChecked,fmt,a1,a2) 00325 #define SimTK_ERRCHK3(cond,whereChecked,fmt,a1,a2,a3) \ 00326 SimTK_ERRCHK3_ALWAYS(cond,whereChecked,fmt,a1,a2,a3) 00327 #define SimTK_ERRCHK4(cond,whereChecked,fmt,a1,a2,a3,a4) \ 00328 SimTK_ERRCHK4_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4) 00329 #define SimTK_ERRCHK5(cond,whereChecked,fmt,a1,a2,a3,a4,a5) \ 00330 SimTK_ERRCHK5_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5) 00331 #define SimTK_ERRCHK6(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) \ 00332 SimTK_ERRCHK6_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 00333 #define SimTK_ERRCHK7(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) \ 00334 SimTK_ERRCHK7_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) 00335 #endif 00336 00337 // ----------------------------------- ASSERT ---------------------------------- 00338 // ASSERT: use this *only* for internal errors, that is, bugs. This must 00339 // not be used to catch usage errors by clients; if you want to catch 00340 // user errors use different exceptions. 00341 // ----------------------------------------------------------------------------- 00342 00343 // This is an assertion that is always active, even in Release mode. 00344 #define SimTK_ASSERT_ALWAYS(cond,msg) \ 00345 do{if(!(cond))SimTK_THROW2(SimTK::Exception::Assert,#cond,(msg));}while(false) 00346 #define SimTK_ASSERT1_ALWAYS(cond,msg,a1) \ 00347 do{if(!(cond))SimTK_THROW3(SimTK::Exception::Assert,#cond,(msg),(a1));}while(false) 00348 #define SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2) \ 00349 do{if(!(cond))SimTK_THROW4(SimTK::Exception::Assert,#cond,(msg),(a1),(a2));}while(false) 00350 #define SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3) \ 00351 do{if(!(cond))SimTK_THROW5(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3));}while(false) 00352 #define SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4) \ 00353 do{if(!(cond))SimTK_THROW6(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4));}while(false) 00354 #define SimTK_ASSERT5_ALWAYS(cond,msg,a1,a2,a3,a4,a5) \ 00355 do{if(!(cond))SimTK_THROW7(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4),(a5));}while(false) 00356 00357 // Note: unlike the system assert() we're putting ours within the header guards. 00358 // So if you want to override NDEBUG do it at the *beginning* (that is, before 00359 // the first #include or #ifdef) of whatever compilation unit you are fiddling with. 00360 #if defined(NDEBUG) && !defined(SimTK_KEEP_ASSERT) 00361 #define SimTK_ASSERT(cond,msg) 00362 #define SimTK_ASSERT(cond,msg) 00363 #define SimTK_ASSERT1(cond,msg,a1) 00364 #define SimTK_ASSERT2(cond,msg,a1,a2) 00365 #define SimTK_ASSERT3(cond,msg,a1,a2,a3) 00366 #define SimTK_ASSERT4(cond,msg,a1,a2,a3,a4) 00367 #define SimTK_ASSERT5(cond,msg,a1,a2,a3,a4,a5) 00368 #else 00369 #define SimTK_ASSERT(cond,msg) SimTK_ASSERT_ALWAYS(cond,msg) 00370 #define SimTK_ASSERT1(cond,msg,a1) SimTK_ASSERT1_ALWAYS(cond,msg,a1) 00371 #define SimTK_ASSERT2(cond,msg,a1,a2) SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2) 00372 #define SimTK_ASSERT3(cond,msg,a1,a2,a3) SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3) 00373 #define SimTK_ASSERT4(cond,msg,a1,a2,a3,a4) SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4) 00374 #define SimTK_ASSERT5(cond,msg,a1,a2,a3,a4,a5) SimTK_ASSERT5_ALWAYS(cond,msg,a1,a2,a3,a4,a5) 00375 #endif 00376 00377 00378 #endif // SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 00379 00380 00381