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 & 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 & 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 & 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