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
52namespace 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
63class 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
142DEFINE_EXC (ArgExc,   BaseExc) 	 // Invalid arguments to a function call
143
144DEFINE_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
149DEFINE_EXC (InputExc, BaseExc) 	 // Invalid input data, e.g. from a file
150
151DEFINE_EXC (IoExc, BaseExc) 	 // Input or output operation failed
152
153DEFINE_EXC (MathExc,  BaseExc) 	 // Arithmetic exception; more specific
154				 // exceptions derived from this class
155				 // are defined in ExcMath.h
156
157DEFINE_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
162DEFINE_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
168DEFINE_EXC (NullExc, BaseExc) 	 // A pointer is inappropriately null.
169
170DEFINE_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
200typedef std::string (* StackTracer) ();
201
202void		setStackTracer (StackTracer stackTracer);
203StackTracer	stackTracer ();
204
205
206//-----------------
207// Inline functions
208//-----------------
209
210inline BaseExc &
211BaseExc::operator = (std::stringstream &s)
212{
213    return assign (s);
214}
215
216
217inline BaseExc &
218BaseExc::operator += (std::stringstream &s)
219{
220    return append (s);
221}
222
223
224inline BaseExc &
225BaseExc::assign (const char *s)
226{
227    std::string::assign(s);
228    return *this;
229}
230
231
232inline BaseExc &
233BaseExc::operator = (const char *s)
234{
235    return assign(s);
236}
237
238
239inline BaseExc &
240BaseExc::append (const char *s)
241{
242    std::string::append(s);
243    return *this;
244}
245
246
247inline BaseExc &
248BaseExc::operator += (const char *s)
249{
250    return append(s);
251}
252
253
254inline const std::string &
255BaseExc::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