Simbody 3.9
Loading...
Searching...
No Matches
Exception.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_EXCEPTION_H_
2#define SimTK_SimTKCOMMON_EXCEPTION_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-15 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
28
29#include <string>
30#include <iostream>
31#include <exception>
32#include <cstdarg>
33#include <cstdio>
34
35namespace SimTK {
36
37namespace Exception {
38
39 // Keeps MS VC++ quiet about sprintf, strcpy, etc.
40#ifdef _MSC_VER
41#pragma warning(push)
42#pragma warning(disable:4996)
43#endif
44
45// SimTK::Exception::Base
46class Base : public std::exception {
47public:
48 explicit Base(const char* fn="<UNKNOWN>", int ln=0)
49 : fileName(fn), lineNo(ln) { }
50 virtual ~Base() throw() { }
51 const std::string& getMessage() const { return msg; }
52 const std::string& getMessageText() const { return text; }
53
54 // override virtual function from std::exception
55 const char* what() const throw() override {return getMessage().c_str();}
56protected:
57 void setMessage(const std::string& msgin) {
58 text = msgin;
59 msg = "SimTK Exception thrown at " + where() + ":\n " + msgin;
60 }
61private:
62 std::string fileName; // where the exception was thrown
63 int lineNo;
64 std::string msg; // a message formatted for display by catcher
65 std::string text; // the original passed-in text
66
67 static std::string shortenFileName(const std::string& fn)
68 { std::string::size_type pos = fn.find_last_of("/\\");
69 if (pos+1>=fn.size()) pos=0;
70 return std::string(fn,(int)(pos+1),(int)(fn.size()-(pos+1)));
71 }
72
73 std::string where() const {
74 const int n = 32;
75 char buf[n];
76 snprintf(buf,n,"%d",lineNo);
77 return shortenFileName(fileName) + ":" + std::string(buf);
78 }
79};
80
87class Assert : public Base {
88public:
89 Assert(const char* fn, int ln, const char* assertion,
90 const char* fmt ...) : Base(fn,ln)
91 {
92 const int n = 1024;
93 char buf[n];
94 va_list args;
95 va_start(args, fmt);
96 vsnprintf(buf, n, fmt, args);
97
98 setMessage("Internal bug detected: " + std::string(buf)
99 + "\n (Assertion '" + std::string(assertion) + "' failed).\n"
100 " Please file an Issue at https://github.com/simbody/simbody/issues.\n"
101 " Include the above information and anything else needed to reproduce the problem.");
102 va_end(args);
103 }
104 virtual ~Assert() throw() { }
105};
106
115class ErrorCheck : public Base {
116public:
117 ErrorCheck(const char* fn, int ln, const char* assertion,
118 const char* whereChecked, // e.g., ClassName::methodName()
119 const char* fmt ...) : Base(fn,ln)
120 {
121 const int n = 1024;
122 char buf[n];
123 va_list args;
124 va_start(args, fmt);
125 vsnprintf(buf, n, fmt, args);
126
127 setMessage("Error detected by Simbody method "
128 + std::string(whereChecked) + ": "
129 + std::string(buf)
130 + "\n (Required condition '" + std::string(assertion) + "' was not met.)\n");
131 va_end(args);
132 }
133 virtual ~ErrorCheck() throw() { }
134};
135
143class APIArgcheckFailed : public Base {
144public:
145 APIArgcheckFailed(const char* fn, int ln, const char* assertion,
146 const char* className, const char* methodName,
147 const char* fmt ...) : Base(fn,ln)
148 {
149 const int n = 1024;
150 char buf[n];
151 va_list args;
152 va_start(args, fmt);
153 vsnprintf(buf, n, fmt, args);
154 setMessage("Bad call to Simbody API method "
155 + std::string(className) + "::" + std::string(methodName) + "(): "
156 + std::string(buf)
157 + "\n (Required condition '" + std::string(assertion) + "' was not met.)");
158 va_end(args);
159 }
160 virtual ~APIArgcheckFailed() throw() { }
161};
162
163
164class IndexOutOfRange : public Base {
165public:
166 IndexOutOfRange(const char* fn, int ln, const char* indexName,
167 long long lb, long long index, long long ub, const char* where)
168 : Base(fn,ln)
169 {
170 const int n = 1024;
171 char buf[n];
172
173 snprintf(buf, n, "Index out of range in %s: expected %lld <= %s < %lld but %s=%lld.",
174 where,lb,indexName,ub,indexName,index);
175 setMessage(std::string(buf));
176 }
177 virtual ~IndexOutOfRange() throw() { }
178};
179
180class SizeOutOfRange : public Base {
181public:
182 SizeOutOfRange(const char* fn, int ln, const char* szName,
183 unsigned long long sz, unsigned long long maxsz, const char* where)
184 : Base(fn,ln)
185 {
186 const int n = 1024;
187 char buf[n];
188
189 snprintf(buf, n, "Size out of range in %s: expected 0 <= %s <= %llu but %s=%llu.",
190 where,szName,maxsz,szName,sz);
191 setMessage(std::string(buf));
192 }
193 virtual ~SizeOutOfRange() throw() { }
194};
195
196class SizeWasNegative : public Base {
197public:
198 SizeWasNegative(const char* fn, int ln, const char* szName,
199 unsigned long long sz, const char* where)
200 : Base(fn,ln)
201 {
202 const int n = 1024;
203 char buf[n];
204
205 snprintf(buf, n, "Size argument was negative in %s: expected 0 <= %s but %s=%llu.",
206 where,szName,szName,sz);
207 setMessage(std::string(buf));
208 }
209 virtual ~SizeWasNegative() throw() { }
210};
211
212class ValueOutOfRange : public Base {
213public:
214 ValueOutOfRange(const char* fn, int ln, const char* valueName,
215 double lowerBound, double value, double upperBound,
216 const char* where)
217 : Base(fn,ln)
218 {
219 const int n = 1024;
220 char buf[n];
221
222 snprintf(buf, n, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
223 where,lowerBound,valueName,upperBound,valueName,value);
224 setMessage(std::string(buf));
225 }
226 virtual ~ValueOutOfRange() throw() { }
227};
228
229class ValueWasNegative : public Base {
230public:
231 ValueWasNegative(const char* fn, int ln, const char* valueName,
232 double value, const char* where)
233 : Base(fn,ln)
234 {
235 const int n = 1024;
236 char buf[n];
237
238 snprintf(buf, n, "Expected non-negative value for %s in %s but got %g.",
239 valueName,where,value);
240 setMessage(std::string(buf));
241 }
242 virtual ~ValueWasNegative() throw() { }
243};
244
245class UnimplementedMethod : public Base {
246public:
247 UnimplementedMethod(const char* fn, int ln, std::string methodName)
248 : Base(fn,ln)
249 {
250 setMessage("The method " + methodName
251 + "is not yet implemented. Please post to the Simbody forum"
252 " to find a workaround or request implementation.");
253 }
254 virtual ~UnimplementedMethod() throw() { }
255};
256
258public:
259 UnimplementedVirtualMethod(const char* fn, int ln,
260 std::string baseClass, std::string methodName)
261 : Base(fn,ln)
262 {
263 setMessage("The base class " + baseClass +
264 " dummy implementation of method " + methodName
265 + "() was invoked because a derived class did not provide an implementation.");
266 }
267 virtual ~UnimplementedVirtualMethod() throw() { }
268};
269
270class IncompatibleValues : public Base {
271public:
272 IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
273 {
274 setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
275 }
276 virtual ~IncompatibleValues() throw() { }
277};
278
280public:
281 OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
282 {
283 setMessage("Operation '" + op + "' allowed only for owners, not views");
284 }
285 virtual ~OperationNotAllowedOnView() throw() { }
286};
287
289public:
290 OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
291 {
292 setMessage("Operation '" + op + "' allowed only for views, not owners");
293 }
294 virtual ~OperationNotAllowedOnOwner() throw() { }
295};
296
298public:
299 OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
300 {
301 setMessage("Operation '" + op + "' not allowed on non-const readonly view");
302 }
304};
305
306// SimTK::Exception::Cant
307class Cant : public Base {
308public:
309 Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
310 {
311 setMessage("Can't perform operation: " + s);
312 }
313 virtual ~Cant() throw() { }
314};
315
316#ifdef _MSC_VER
317#pragma warning(pop)
318#endif
319
320} // namespace Exception
321} // namespace SimTK
322
323#define SimTK_THROW(exc) \
324 throw exc(__FILE__, __LINE__)
325#define SimTK_THROW1(exc,a1) \
326 throw exc(__FILE__, __LINE__,a1)
327#define SimTK_THROW2(exc,a1,a2) \
328 throw exc(__FILE__, __LINE__,a1,a2)
329#define SimTK_THROW3(exc,a1,a2,a3) \
330 throw exc(__FILE__, __LINE__,a1,a2,a3)
331#define SimTK_THROW4(exc,a1,a2,a3,a4) \
332 throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
333#define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
334 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
335#define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
336 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
337#define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
338 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
339#define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
340 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
341#define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
342 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
343#define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
344 throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
345
346#endif // SimTK_SimTKCOMMON_EXCEPTION_H_
347
Mandatory first inclusion for any Simbody source or header file.
This is for reporting problems detected by checking the caller's supplied arguments to a SimTK API me...
Definition Exception.h:143
APIArgcheckFailed(const char *fn, int ln, const char *assertion, const char *className, const char *methodName, const char *fmt ...)
Definition Exception.h:145
virtual ~APIArgcheckFailed()
Definition Exception.h:160
This is for reporting internally-detected bugs only, not problems induced by confused users (that is,...
Definition Exception.h:87
virtual ~Assert()
Definition Exception.h:104
Assert(const char *fn, int ln, const char *assertion, const char *fmt ...)
Definition Exception.h:89
Definition Exception.h:46
const char * what() const override
Definition Exception.h:55
virtual ~Base()
Definition Exception.h:50
Base(const char *fn="<UNKNOWN>", int ln=0)
Definition Exception.h:48
const std::string & getMessageText() const
Definition Exception.h:52
void setMessage(const std::string &msgin)
Definition Exception.h:57
const std::string & getMessage() const
Definition Exception.h:51
Definition Exception.h:307
Cant(const char *fn, int ln, const std::string &s)
Definition Exception.h:309
virtual ~Cant()
Definition Exception.h:313
This is for reporting errors occurring during execution of SimTK core methods, beyond those caused by...
Definition Exception.h:115
ErrorCheck(const char *fn, int ln, const char *assertion, const char *whereChecked, const char *fmt ...)
Definition Exception.h:117
virtual ~ErrorCheck()
Definition Exception.h:133
Definition Exception.h:270
IncompatibleValues(const char *fn, int ln, std::string src, std::string dest)
Definition Exception.h:272
virtual ~IncompatibleValues()
Definition Exception.h:276
Definition Exception.h:164
virtual ~IndexOutOfRange()
Definition Exception.h:177
IndexOutOfRange(const char *fn, int ln, const char *indexName, long long lb, long long index, long long ub, const char *where)
Definition Exception.h:166
virtual ~OperationNotAllowedOnNonconstReadOnlyView()
Definition Exception.h:303
OperationNotAllowedOnNonconstReadOnlyView(const char *fn, int ln, const std::string &op)
Definition Exception.h:299
virtual ~OperationNotAllowedOnOwner()
Definition Exception.h:294
OperationNotAllowedOnOwner(const char *fn, int ln, const std::string &op)
Definition Exception.h:290
OperationNotAllowedOnView(const char *fn, int ln, const std::string &op)
Definition Exception.h:281
virtual ~OperationNotAllowedOnView()
Definition Exception.h:285
Definition Exception.h:180
SizeOutOfRange(const char *fn, int ln, const char *szName, unsigned long long sz, unsigned long long maxsz, const char *where)
Definition Exception.h:182
virtual ~SizeOutOfRange()
Definition Exception.h:193
Definition Exception.h:196
virtual ~SizeWasNegative()
Definition Exception.h:209
SizeWasNegative(const char *fn, int ln, const char *szName, unsigned long long sz, const char *where)
Definition Exception.h:198
Definition Exception.h:245
UnimplementedMethod(const char *fn, int ln, std::string methodName)
Definition Exception.h:247
virtual ~UnimplementedMethod()
Definition Exception.h:254
UnimplementedVirtualMethod(const char *fn, int ln, std::string baseClass, std::string methodName)
Definition Exception.h:259
virtual ~UnimplementedVirtualMethod()
Definition Exception.h:267
Definition Exception.h:212
virtual ~ValueOutOfRange()
Definition Exception.h:226
ValueOutOfRange(const char *fn, int ln, const char *valueName, double lowerBound, double value, double upperBound, const char *where)
Definition Exception.h:214
Definition Exception.h:229
ValueWasNegative(const char *fn, int ln, const char *valueName, double value, const char *where)
Definition Exception.h:231
virtual ~ValueWasNegative()
Definition Exception.h:242
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition Assembler.h:37