1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34
35
36
37 #ifndef INCLUDED_IEXBASEEXC_H
38 #define INCLUDED_IEXBASEEXC_H
39
40
41 //----------------------------------------------------------
42 //
43 // A general exception base class, and a few
44 // useful exceptions derived from the base class.
45 //
46 //----------------------------------------------------------
47
48 #include <string>
49 #include <exception>
50 #include <sstream>
51
52 namespace Iex {
53
54 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
55 // Tell MS VC++ to suppress exception specification warnings
56 #pragma warning(disable:4290)
57 #endif
58
59 //-------------------------------
60 // Our most basic exception class
61 //-------------------------------
62
63 class BaseExc: public std::string, public std::exception
64 {
65 public:
66
67 //----------------------------
68 // Constructors and destructor
69 //----------------------------
70
71 BaseExc (const char *s = 0) throw(); // std::string (s)
72 BaseExc (const std::string &s) throw(); // std::string (s)
73 BaseExc (std::stringstream &s) throw(); // std::string (s.str())
74
75 BaseExc (const BaseExc &be) throw();
76 virtual ~BaseExc () throw ();
77
78 //--------------------------------------------
79 // what() method -- e.what() returns e.c_str()
80 //--------------------------------------------
81
82 virtual const char * what () const throw ();
83
84
85 //--------------------------------------------------
86 // Convenient methods to change the exception's text
87 //--------------------------------------------------
88
89 BaseExc & assign (std::stringstream &s); // assign (s.str())
90 BaseExc & operator = (std::stringstream &s);
91
92 BaseExc & append (std::stringstream &s); // append (s.str())
93 BaseExc & operator += (std::stringstream &s);
94
95
96 //--------------------------------------------------
97 // These methods from the base class get obscured by
98 // the definitions above.
99 //--------------------------------------------------
100
101 BaseExc & assign (const char *s);
102 BaseExc & operator = (const char *s);
103
104 BaseExc & append (const char *s);
105 BaseExc & operator += (const char *s);
106
107
108 //--------------------------------------------------
109 // Stack trace for the point at which the exception
110 // was thrown. The stack trace will be an empty
111 // string unless a working stack-tracing routine
112 // has been installed (see below, setStackTracer()).
113 //--------------------------------------------------
114
115 const std::string & stackTrace () const;
116
117 private:
118
119 std::string _stackTrace;
120 };
121
122
123 //-----------------------------------------------------
124 // A macro to save typing when declararing an exception
125 // class derived directly or indirectly from BaseExc:
126 //-----------------------------------------------------
127
128 #define DEFINE_EXC(name, base) \
129 class name: public base \
130 { \
131 public: \
132 name (const char* text=0) throw(): base (text) {} \
133 name (const std::string &text) throw(): base (text) {} \
134 name (std::stringstream &text) throw(): base (text) {} \
135 };
136
137
138 //--------------------------------------------------------
139 // Some exceptions which should be useful in most programs
140 //--------------------------------------------------------
141
142 DEFINE_EXC (ArgExc, BaseExc) // Invalid arguments to a function call
143
144 DEFINE_EXC (LogicExc, BaseExc) // General error in a program's logic,
145 // for example, a function was called
146 // in a context where the call does
147 // not make sense.
148
149 DEFINE_EXC (InputExc, BaseExc) // Invalid input data, e.g. from a file
150
151 DEFINE_EXC (IoExc, BaseExc) // Input or output operation failed
152
153 DEFINE_EXC (MathExc, BaseExc) // Arithmetic exception; more specific
154 // exceptions derived from this class
155 // are defined in ExcMath.h
156
157 DEFINE_EXC (ErrnoExc, BaseExc) // Base class for exceptions corresponding
158 // to errno values (see errno.h); more
159 // specific exceptions derived from this
160 // class are defined in ExcErrno.h
161
162 DEFINE_EXC (NoImplExc, BaseExc) // Missing method exception e.g. from a
163 // call to a method that is only partially
164 // or not at all implemented. A reminder
165 // to lazy software people to get back
166 // to work.
167
168 DEFINE_EXC (NullExc, BaseExc) // A pointer is inappropriately null.
169
170 DEFINE_EXC (TypeExc, BaseExc) // An object is an inappropriate type,
171 // i.e. a dynamnic_cast failed.
172
173
174 //----------------------------------------------------------------------
175 // Stack-tracing support:
176 //
177 // setStackTracer(st)
178 //
179 // installs a stack-tracing routine, st, which will be called from
180 // class BaseExc's constructor every time an exception derived from
181 // BaseExc is thrown. The stack-tracing routine should return a
182 // string that contains a printable representation of the program's
183 // current call stack. This string will be stored in the BaseExc
184 // object; the string is accesible via the BaseExc::stackTrace()
185 // method.
186 //
187 // setStackTracer(0)
188 //
189 // removes the current stack tracing routine. When an exception
190 // derived from BaseExc is thrown, the stack trace string stored
191 // in the BaseExc object will be empty.
192 //
193 // stackTracer()
194 //
195 // returns a pointer to the current stack-tracing routine, or 0
196 // if there is no current stack stack-tracing routine.
197 //
198 //----------------------------------------------------------------------
199
200 typedef std::string (* StackTracer) ();
201
202 void setStackTracer (StackTracer stackTracer);
203 StackTracer stackTracer ();
204
205
206 //-----------------
207 // Inline functions
208 //-----------------
209
210 inline BaseExc &
211 BaseExc::operator = (std::stringstream &s)
212 {
213 return assign (s);
214 }
215
216
217 inline BaseExc &
218 BaseExc::operator += (std::stringstream &s)
219 {
220 return append (s);
221 }
222
223
224 inline BaseExc &
assign(const char * s)225 BaseExc::assign (const char *s)
226 {
227 std::string::assign(s);
228 return *this;
229 }
230
231
232 inline BaseExc &
233 BaseExc::operator = (const char *s)
234 {
235 return assign(s);
236 }
237
238
239 inline BaseExc &
append(const char * s)240 BaseExc::append (const char *s)
241 {
242 std::string::append(s);
243 return *this;
244 }
245
246
247 inline BaseExc &
248 BaseExc::operator += (const char *s)
249 {
250 return append(s);
251 }
252
253
254 inline const std::string &
stackTrace()255 BaseExc::stackTrace () const
256 {
257 return _stackTrace;
258 }
259
260 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
261 #pragma warning(default:4290)
262 #endif
263
264 } // namespace Iex
265
266 #endif
267