1 #ifndef SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 2 #define SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 3 4 /* -------------------------------------------------------------------------- * 5 * Simbody(tm): SimTKcommon * 6 * -------------------------------------------------------------------------- * 7 * This is part of the SimTK biosimulation toolkit originating from * 8 * Simbios, the NIH National Center for Physics-Based Simulation of * 9 * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 11 * * 12 * Portions copyright (c) 2005-12 Stanford University and the Authors. * 13 * Authors: Michael Sherman * 14 * Contributors: * 15 * * 16 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 17 * not use this file except in compliance with the License. You may obtain a * 18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 19 * * 20 * Unless required by applicable law or agreed to in writing, software * 21 * distributed under the License is distributed on an "AS IS" BASIS, * 22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 23 * See the License for the specific language governing permissions and * 24 * limitations under the License. * 25 * -------------------------------------------------------------------------- */ 26 27 /** @file 28 * This file contains macros which are convenient to use for 29 * sprinkling error checking around liberally in SimTK programs, a 30 * practice which is highly encouraged. You can think of this as 31 * a generalization of the standard assert() macro. By default, 32 * these macros evaporate completely in a release build, but are 33 * present in any debug build. Macros are also provided which are 34 * always present in cases where the error checking is not a 35 * performance problem, and those should be used in preference 36 * to the disappearing ones when appropriate. Also, you can force 37 * the disappearing macros to remain present on a file-by-file basis, 38 * primarily for use in debugging those annoying problems which only 39 * occur in release builds and won't reproduce in a debug build. 40 * 41 * Most macros have a similar structure, something like this: 42 * <pre> 43 * SimTK_MACRONAME[nargs][_ALWAYS](cond, printfString [, args...]) 44 * for example 45 * SimTK_ASSERT3(lower<count && count<upper, 46 * "expected %d < count < %d but count=%d", 47 * lower, upper, count); 48 * or 49 * SimTK_ASSERT3_ALWAYS(lower<count && count<upper, 50 * "expected %d < count < %d but count=%d", 51 * lower, upper, count); 52 * </pre> 53 * To override the disappearance of the non-ALWAYS macros, your 54 * compilation should define a preprocessor symbols like 55 * SimTK_KEEP_ASSERT, SimTK_KEEP_ERRCHK, etc. 56 * 57 * These macros will also capture the current file name and line 58 * number for reporting to developers when appropriate, and those 59 * with a condition that failed will include the condition in the 60 * message. 61 * 62 * Note that these are *global* symbols, so we use the reserved 63 * SimTK_ name prefix (since we can't use the SimTK:: namespace 64 * for macros) to attempt to avoid pollution of user programs. 65 * 66 * We distinguish between macros which are used as internal 67 * "bugcatchers" and those which are used to report errors to 68 * API users. The C++ exception mechanism is used in both circumstances 69 * but the meaning and intended audience is quite different. Any 70 * macro with 'ASSERT' in the name represents an internal error 71 * which cannot be attributed to user misbehavior. Other macros 72 * are for communicating with users. Those need to be carefully documented 73 * so that users can selectively catch the exceptions when appropriate. 74 */ 75 76 #include "SimTKcommon/internal/common.h" 77 #include "SimTKcommon/internal/Exception.h" 78 79 #include <string> 80 #include <iostream> 81 #include <exception> 82 83 // --------------------------------- RANGECHECK -------------------------------- 84 // These exceptions are to be used for situations in which a user of a SimTK 85 // API method screws up by providing bad indices or dimensions. These are special 86 // cases of the more general APIARGCHECK macros, providing "canned" error messages 87 // for several common situations. Although there are several different macro 88 // names here, all are controlled by SimTK_KEEP_RANGECHECK to allow enabling of 89 // these index- and size-validating tests together in Release mode. 90 // 91 // INDEXCHECK: Note that we allow the index to be equal to the lower 92 // bound (zero) but it must be strictly less than the upper bound. 93 // SIZECHECK: A size or size expression must be >= 0 and less than OR EQUAL 94 // to the maximum size. 95 // SIZECHECK_NONNEG: A size argument must be >= 0. 96 // VALUECHECK: A floating point is required to be within a certain range. 97 // VALUECHECK_NONNEG: A floating point argument must be non-negative. 98 // 99 // TODO: SHAPECHECK, DOMAINCHECK 100 // ----------------------------------------------------------------------------- 101 102 // This is a rangecheck that is always present, even in Release mode. This may be 103 // applied both to signed and unsigned types (the latter are always nonnegative) so 104 // to avoid warnings we use the isIndexInRange() method which doesn't perform 105 // a nonnegativity check on unsigned quantities. 106 #define SimTK_INDEXCHECK_ALWAYS(ix,ub,where) \ 107 do{if(!isIndexInRange((ix),(ub)))SimTK_THROW5(SimTK::Exception::IndexOutOfRange, \ 108 #ix,0,(ix),(ub),(where));}while(false) 109 110 // This is a rangecheck that is always present, even in Release mode. This may be 111 // applied both to signed and unsigned types (the latter are always nonnegative) so 112 // to avoid warnings we use the isSizeInRange() method which doesn't perform 113 // a nonnegativity check on unsigned quantities. 114 #define SimTK_SIZECHECK_ALWAYS(sz,maxsz,where) \ 115 do{if(!isSizeInRange((sz),(maxsz)))SimTK_THROW4(SimTK::Exception::SizeOutOfRange, \ 116 #sz,(sz),(maxsz),(where));}while(false) 117 118 // This is a rangecheck that is always present, even in Release mode. Use 119 // isNonnegative() here in case sz is an unsigned type to avoid compiler 120 // warning. 121 #define SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where) \ 122 do{if(!isNonnegative(sz))SimTK_THROW3(SimTK::Exception::SizeWasNegative, \ 123 #sz,(sz),(where));}while(false) 124 125 // Similar checks for floating point values. 126 127 #define SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where) \ 128 do{if(!((lb)<=(val)&&(val)<=(ub)))SimTK_THROW5(SimTK::Exception::ValueOutOfRange, \ 129 (valName),(lb),(val),(ub),(where));}while(false) 130 131 132 #define SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where) \ 133 do{if((val)<0)SimTK_THROW3(SimTK::Exception::ValueWasNegative, \ 134 (valName),(val),(where));}while(false) 135 136 137 138 #if defined(NDEBUG) && !defined(SimTK_KEEP_RANGECHECK) 139 #define SimTK_INDEXCHECK(ix,ub,where) 140 #define SimTK_SIZECHECK(sz,maxsz,where) 141 #define SimTK_SIZECHECK_NONNEG(sz,where) 142 #define SimTK_VALUECHECK(lb,val,ub,valName,where) 143 #define SimTK_VALUECHECK_NONNEG(val,valName,where) 144 #else 145 #define SimTK_INDEXCHECK(ix,ub,where) SimTK_INDEXCHECK_ALWAYS(ix,ub,where) 146 #define SimTK_SIZECHECK(sz,maxsz,where) SimTK_SIZECHECK_ALWAYS(sz,maxsz,where) 147 #define SimTK_SIZECHECK_NONNEG(sz,where) SimTK_SIZECHECK_NONNEG_ALWAYS(sz,where) 148 #define SimTK_VALUECHECK(lb,val,ub,valName,where) SimTK_VALUECHECK_ALWAYS(lb,val,ub,valName,where) 149 #define SimTK_VALUECHECK_NONNEG(val,valName,where) SimTK_VALUECHECK_NONNEG_ALWAYS(val,valName,where) 150 #endif 151 152 153 // --------------------------------- STAGECHECK -------------------------------- 154 // These exceptions are to be used for situations in which a 155 // user of an API screws up by attempting to access something in the 156 // state before it has been realized to the appropriate stage. 157 // 158 // STAGECHECK_TOPOLOGY_REALIZED: Check that realizeTopology() has been done 159 // since the last topological change. 160 // STAGECHECK_EQ: Check that the current stage is == a particular stage. 161 // STAGECHECK_GE: Check that the current stage is >= a particular stage. 162 // STAGECHECK_LT: Check that the current stage is < a particular stage. 163 // STAGECHECK_RANGE: Check that lower <= stage <= upper. 164 // ----------------------------------------------------------------------------- 165 166 // These are stagechecks that is always present, even in Release mode. 167 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodNm) \ 168 do{if(!(cond)) SimTK_THROW3(SimTK::Exception::RealizeTopologyMustBeCalledFirst, \ 169 (objType),(objName),(methodNm));}while(false) 170 #define SimTK_STAGECHECK_TOPOLOGY_VERSION_ALWAYS(sysTopoVersion, \ 171 stateTopoVersion,objType,objName,methodNm) \ 172 do{if((stateTopoVersion)!=(sysTopoVersion)) \ 173 SimTK_THROW5(SimTK::Exception::StateAndSystemTopologyVersionsMustMatch, \ 174 (objType),(objName),(methodNm), \ 175 (int)(sysTopoVersion),(int)(stateTopoVersion));} \ 176 while(false) 177 #define SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm) \ 178 do{if((currentStage)!=(targetStage)) SimTK_THROW3(SimTK::Exception::StageIsWrong, \ 179 (currentStage),(targetStage),(methodNm));}while(false) 180 #define SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm) \ 181 do{if(!((currentStage)>=(targetStage))) SimTK_THROW3(SimTK::Exception::StageTooLow, \ 182 (currentStage),(targetStage),(methodNm));}while(false) 183 #define SimTK_STAGECHECK_LT_ALWAYS(currentStage,targetStage,methodNm) \ 184 do{if((currentStage)>=(targetStage)) SimTK_THROW3(SimTK::Exception::StageTooHigh, \ 185 (currentStage),(targetStage),(methodNm));}while(false) 186 #define SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm) \ 187 do{if(!((lower)<=(current)&&(current)<=(upper))) SimTK_THROW4(SimTK::Exception::StageOutOfRange, \ 188 (lower),(current),(upper),(methodNm));}while(false) 189 190 // This one is present only in Debug mode or if SimTK_KEEP_STAGECHECK is explicitly defined. 191 #if defined(NDEBUG) && !defined(SimTK_KEEP_STAGECHECK) 192 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED(cond,objType,objName,methodName) 193 #define SimTK_STAGECHECK_TOPOLOGY_VERSIONS(sysTopoVersion,stateTopoVersion,\ 194 objType,objName,methodNm) 195 #define SimTK_STAGECHECK_EQ(currentStage,targetStage,methodNm) 196 #define SimTK_STAGECHECK_GE(currentStage,targetStage,methodNm) 197 #define SimTK_STAGECHECK_LT(currentStage,targetStage,methodNm) 198 #define SimTK_STAGECHECK_RANGE(lower,current,upper,methodNm) 199 #else 200 #define SimTK_STAGECHECK_TOPOLOGY_REALIZED(cond,objType,objName,methodName) \ 201 SimTK_STAGECHECK_TOPOLOGY_REALIZED_ALWAYS(cond,objType,objName,methodName) 202 #define SimTK_STAGECHECK_TOPOLOGY_VERSION(sysTopoVersion,stateTopoVersion, \ 203 objType,objName,methodNm) \ 204 SimTK_STAGECHECK_TOPOLOGY_VERSION_ALWAYS(sysTopoVersion,stateTopoVersion,\ 205 objType,objName,methodNm) 206 #define SimTK_STAGECHECK_EQ(currentStage,targetStage,methodNm) \ 207 SimTK_STAGECHECK_EQ_ALWAYS(currentStage,targetStage,methodNm) 208 #define SimTK_STAGECHECK_GE(currentStage,targetStage,methodNm) \ 209 SimTK_STAGECHECK_GE_ALWAYS(currentStage,targetStage,methodNm) 210 #define SimTK_STAGECHECK_LT(currentStage,targetStage,methodNm) \ 211 SimTK_STAGECHECK_LE_ALWAYS(currentStage,targetStage,methodNm) 212 #define SimTK_STAGECHECK_RANGE(lower,current,upper,methodNm) \ 213 SimTK_STAGECHECK_RANGE_ALWAYS(lower,current,upper,methodNm) 214 #endif 215 216 // -------------------------------- APIARGCHECK -------------------------------- 217 // These should be used to catch all manner of problems with the arguments passed 218 // in an API user's call to a method that is part of a SimTK API. Note that these 219 // are intended for direct consumption by an application programmer using a SimTK 220 // API, so should be wordy and helpful. These macros accept printf-style format 221 // strings and arguments of whatever are the appropriate types for those formats. 222 // ----------------------------------------------------------------------------- 223 224 #define SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg) \ 225 do{if(!(cond))SimTK_THROW4(SimTK::Exception::APIArgcheckFailed, \ 226 #cond,(className),(methodName),(msg)); \ 227 }while(false) 228 #define SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1) \ 229 do{if(!(cond))SimTK_THROW5(SimTK::Exception::APIArgcheckFailed, \ 230 #cond,(className),(methodName),(fmt),(a1)); \ 231 }while(false) 232 #define SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2) \ 233 do{if(!(cond))SimTK_THROW6(SimTK::Exception::APIArgcheckFailed, \ 234 #cond,(className),(methodName),(fmt),(a1),(a2)); \ 235 }while(false) 236 #define SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3) \ 237 do{if(!(cond))SimTK_THROW7(SimTK::Exception::APIArgcheckFailed, \ 238 #cond,(className),(methodName),(fmt),(a1),(a2),(a3)); \ 239 }while(false) 240 #define SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4) \ 241 do{if(!(cond))SimTK_THROW8(SimTK::Exception::APIArgcheckFailed, \ 242 #cond,(className),(methodName),(fmt),(a1),(a2),(a3),(a4)); \ 243 }while(false) 244 #define SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5) \ 245 do{if(!(cond))SimTK_THROW9(SimTK::Exception::APIArgcheckFailed, \ 246 #cond,(className),(methodName),(fmt),(a1),(a2),(a3),(a4),(a5)); \ 247 }while(false) 248 249 #if defined(NDEBUG) && !defined(SimTK_KEEP_APIARGCHECK) 250 #define SimTK_APIARGCHECK(cond,className,methodName,msg) 251 #define SimTK_APIARGCHECK1(cond,className,methodName,fmt,a1) 252 #define SimTK_APIARGCHECK2(cond,className,methodName,fmt,a1,a2) 253 #define SimTK_APIARGCHECK3(cond,className,methodName,fmt,a1,a2,a3) 254 #define SimTK_APIARGCHECK4(cond,className,methodName,fmt,a1,a2,a3,a4) 255 #define SimTK_APIARGCHECK5(cond,className,methodName,fmt,a1,a2,a3,a4,a5) 256 #else 257 #define SimTK_APIARGCHECK(cond,className,methodName,msg) \ 258 SimTK_APIARGCHECK_ALWAYS(cond,className,methodName,msg) 259 #define SimTK_APIARGCHECK1(cond,className,methodName,fmt,a1) \ 260 SimTK_APIARGCHECK1_ALWAYS(cond,className,methodName,fmt,a1) 261 #define SimTK_APIARGCHECK2(cond,className,methodName,fmt,a1,a2) \ 262 SimTK_APIARGCHECK2_ALWAYS(cond,className,methodName,fmt,a1,a2) 263 #define SimTK_APIARGCHECK3(cond,className,methodName,fmt,a1,a2,a3) \ 264 SimTK_APIARGCHECK3_ALWAYS(cond,className,methodName,fmt,a1,a2,a3) 265 #define SimTK_APIARGCHECK4(cond,className,methodName,fmt,a1,a2,a3,a4) \ 266 SimTK_APIARGCHECK4_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4) 267 #define SimTK_APIARGCHECK5(cond,className,methodName,fmt,a1,a2,a3,a4,a5) \ 268 SimTK_APIARGCHECK5_ALWAYS(cond,className,methodName,fmt,a1,a2,a3,a4,a5) 269 #endif 270 271 272 // ----------------------------------- ERRCHK ---------------------------------- 273 // ERRCHK: these should be used to catch all manner of problems that occur 274 // during execution of an API user's request by a method that is part of 275 // a SimTK API. Note that these are intended for direct consumption by 276 // an application programmer using a SimTK API, so should be wordy and 277 // helpful. These macros accept printf-style format strings and arguments 278 // of whatever are the appropriate types for those formats. 279 // ----------------------------------------------------------------------------- 280 281 #define SimTK_ERRCHK_ALWAYS(cond,whereChecked,msg) \ 282 do{if(!(cond))SimTK_THROW3(SimTK::Exception::ErrorCheck, \ 283 #cond,(whereChecked),(msg)); \ 284 }while(false) 285 #define SimTK_ERRCHK1_ALWAYS(cond,whereChecked,fmt,a1) \ 286 do{if(!(cond))SimTK_THROW4(SimTK::Exception::ErrorCheck, \ 287 #cond,(whereChecked),(fmt),(a1)); \ 288 }while(false) 289 #define SimTK_ERRCHK2_ALWAYS(cond,whereChecked,fmt,a1,a2) \ 290 do{if(!(cond))SimTK_THROW5(SimTK::Exception::ErrorCheck, \ 291 #cond,(whereChecked),(fmt),(a1),(a2)); \ 292 }while(false) 293 #define SimTK_ERRCHK3_ALWAYS(cond,whereChecked,fmt,a1,a2,a3) \ 294 do{if(!(cond))SimTK_THROW6(SimTK::Exception::ErrorCheck, \ 295 #cond,(whereChecked),(fmt),(a1),(a2),(a3)); \ 296 }while(false) 297 #define SimTK_ERRCHK4_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4) \ 298 do{if(!(cond))SimTK_THROW7(SimTK::Exception::ErrorCheck, \ 299 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4)); \ 300 }while(false) 301 #define SimTK_ERRCHK5_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5) \ 302 do{if(!(cond))SimTK_THROW8(SimTK::Exception::ErrorCheck, \ 303 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5)); \ 304 }while(false) 305 #define SimTK_ERRCHK6_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) \ 306 do{if(!(cond))SimTK_THROW9(SimTK::Exception::ErrorCheck, \ 307 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5),(a6)); \ 308 }while(false) 309 #define SimTK_ERRCHK7_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) \ 310 do{if(!(cond))SimTK_THROW10(SimTK::Exception::ErrorCheck, \ 311 #cond,(whereChecked),(fmt),(a1),(a2),(a3),(a4),(a5),(a6),(a7)); \ 312 }while(false) 313 314 #if defined(NDEBUG) && !defined(SimTK_KEEP_ERRCHK) 315 #define SimTK_ERRCHK(cond,whereChecked,msg) 316 #define SimTK_ERRCHK1(cond,whereChecked,fmt,a1) 317 #define SimTK_ERRCHK2(cond,whereChecked,fmt,a1,a2) 318 #define SimTK_ERRCHK3(cond,whereChecked,fmt,a1,a2,a3) 319 #define SimTK_ERRCHK4(cond,whereChecked,fmt,a1,a2,a3,a4) 320 #define SimTK_ERRCHK5(cond,whereChecked,fmt,a1,a2,a3,a4,a5) 321 #define SimTK_ERRCHK6(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 322 #define SimTK_ERRCHK7(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 323 #else 324 #define SimTK_ERRCHK(cond,whereChecked,msg) \ 325 SimTK_ERRCHK_ALWAYS(cond,whereChecked,msg) 326 #define SimTK_ERRCHK1(cond,whereChecked,fmt,a1) \ 327 SimTK_ERRCHK1_ALWAYS(cond,whereChecked,fmt,a1) 328 #define SimTK_ERRCHK2(cond,whereChecked,fmt,a1,a2) \ 329 SimTK_ERRCHK2_ALWAYS(cond,whereChecked,fmt,a1,a2) 330 #define SimTK_ERRCHK3(cond,whereChecked,fmt,a1,a2,a3) \ 331 SimTK_ERRCHK3_ALWAYS(cond,whereChecked,fmt,a1,a2,a3) 332 #define SimTK_ERRCHK4(cond,whereChecked,fmt,a1,a2,a3,a4) \ 333 SimTK_ERRCHK4_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4) 334 #define SimTK_ERRCHK5(cond,whereChecked,fmt,a1,a2,a3,a4,a5) \ 335 SimTK_ERRCHK5_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5) 336 #define SimTK_ERRCHK6(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) \ 337 SimTK_ERRCHK6_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6) 338 #define SimTK_ERRCHK7(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) \ 339 SimTK_ERRCHK7_ALWAYS(cond,whereChecked,fmt,a1,a2,a3,a4,a5,a6,a7) 340 #endif 341 342 // ----------------------------------- ASSERT ---------------------------------- 343 // ASSERT: use this *only* for internal errors, that is, bugs. This must 344 // not be used to catch usage errors by clients; if you want to catch 345 // user errors use different exceptions. 346 // ----------------------------------------------------------------------------- 347 348 // This is an assertion that is always active, even in Release mode. 349 #define SimTK_ASSERT_ALWAYS(cond,msg) \ 350 do{if(!(cond))SimTK_THROW2(SimTK::Exception::Assert,#cond,(msg));}while(false) 351 #define SimTK_ASSERT1_ALWAYS(cond,msg,a1) \ 352 do{if(!(cond))SimTK_THROW3(SimTK::Exception::Assert,#cond,(msg),(a1));}while(false) 353 #define SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2) \ 354 do{if(!(cond))SimTK_THROW4(SimTK::Exception::Assert,#cond,(msg),(a1),(a2));}while(false) 355 #define SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3) \ 356 do{if(!(cond))SimTK_THROW5(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3));}while(false) 357 #define SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4) \ 358 do{if(!(cond))SimTK_THROW6(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4));}while(false) 359 #define SimTK_ASSERT5_ALWAYS(cond,msg,a1,a2,a3,a4,a5) \ 360 do{if(!(cond))SimTK_THROW7(SimTK::Exception::Assert,#cond,(msg),(a1),(a2),(a3),(a4),(a5));}while(false) 361 362 // Note: unlike the system assert() we're putting ours within the header guards. 363 // So if you want to override NDEBUG do it at the *beginning* (that is, before 364 // the first #include or #ifdef) of whatever compilation unit you are fiddling with. 365 #if defined(NDEBUG) && !defined(SimTK_KEEP_ASSERT) 366 #define SimTK_ASSERT(cond,msg) 367 #define SimTK_ASSERT1(cond,msg,a1) 368 #define SimTK_ASSERT2(cond,msg,a1,a2) 369 #define SimTK_ASSERT3(cond,msg,a1,a2,a3) 370 #define SimTK_ASSERT4(cond,msg,a1,a2,a3,a4) 371 #define SimTK_ASSERT5(cond,msg,a1,a2,a3,a4,a5) 372 #else 373 #define SimTK_ASSERT(cond,msg) SimTK_ASSERT_ALWAYS(cond,msg) 374 #define SimTK_ASSERT1(cond,msg,a1) SimTK_ASSERT1_ALWAYS(cond,msg,a1) 375 #define SimTK_ASSERT2(cond,msg,a1,a2) SimTK_ASSERT2_ALWAYS(cond,msg,a1,a2) 376 #define SimTK_ASSERT3(cond,msg,a1,a2,a3) SimTK_ASSERT3_ALWAYS(cond,msg,a1,a2,a3) 377 #define SimTK_ASSERT4(cond,msg,a1,a2,a3,a4) SimTK_ASSERT4_ALWAYS(cond,msg,a1,a2,a3,a4) 378 #define SimTK_ASSERT5(cond,msg,a1,a2,a3,a4,a5) SimTK_ASSERT5_ALWAYS(cond,msg,a1,a2,a3,a4,a5) 379 #endif 380 381 382 #endif // SimTK_SimTKCOMMON_EXCEPTION_MACROS_H_ 383 384 385 386