00001 /* 00002 * wave_ex.h 00003 * 00004 * Copyright (C) 2007-2009 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Simple exception utility class. 00032 */ 00033 00034 #ifndef WAVEPACKET_EXCEPTION_H__ 00035 #define WAVEPACKET_EXCEPTION_H__ 00036 00037 00038 // includes -------------------------------------------------------------------- 00039 #include "common/common.h" 00040 00041 #include <sstream> 00042 00043 /// \ingroup common 00044 /*@{*/ 00045 00046 00047 00048 /// DON'T USE THIS CLASS. Use wave_ex instead. 00049 class wave_exception : public std::exception { 00050 public: 00051 wave_exception(IN const std::string& what) : m_what(what) { } 00052 ~wave_exception(void) throw() { } 00053 00054 virtual const char * what(void) const throw() { 00055 return m_what.c_str(); 00056 } 00057 00058 private: 00059 std::string m_what; 00060 }; 00061 00062 00063 00064 /// Smart exception object. 00065 /// 00066 /// Once you create one of these on the stack it will 00067 /// automatically throw in the destructor. It can be caught as a 00068 /// std::exception. 00069 /// 00070 /// Once you create it, use it like a stringstream. 00071 /// 00072 /// Use the provided helper macro to construct the exception object, this 00073 /// will also provide the file and line number: 00074 /// \code 00075 /// function(void) { 00076 /// if (something_bad()) { 00077 /// WAVE_EX(wex); 00078 /// wex << "Something bad just happened!"; 00079 /// wex << more_info(); 00080 /// wex << "Good luck!"; 00081 /// } // <-- automatically throws here 00082 /// } 00083 /// \endcode 00084 class wave_ex : public std::ostringstream { 00085 public: 00086 wave_ex(IN const char * filename, IN int line) : m_thrown(false) { 00087 fprintf(stderr, "********************************\n"); 00088 fprintf(stderr, 00089 "%s(%d): Throwing exception from here!\n", 00090 filename, line); 00091 } 00092 ~wave_ex(void) { 00093 if (!m_thrown) { 00094 m_thrown = true; 00095 this->Throw(); 00096 } 00097 } 00098 private: 00099 // hidden default constructor (must use the one above) ----------------- 00100 wave_ex(void) throw() : m_thrown(false) { } 00101 00102 // private helper methods ---------------------------------------------- 00103 void Throw(void) throw(std::exception) { 00104 m_thrown = true; 00105 fprintf(stderr, "%s\n", this->str().c_str()); 00106 fprintf(stderr, "********************************\n"); 00107 throw wave_exception(this->str()); 00108 } 00109 00110 // private member data ------------------------------------------------- 00111 bool m_thrown; // true if we've already thrown 00112 }; 00113 00114 00115 /// handy macro to define an exception object, including file and line 00116 #define WAVE_EX(name) wave_ex name ( __FILE__ , __LINE__ ) 00117 00118 00119 /// handy macro to quickly throw with a simple message if the given expression 00120 /// is false 00121 #define ASSERT_THROW(exp, msg) { \ 00122 if (!(exp)) { \ 00123 WAVE_EX(wex); \ 00124 wex << "Assertion failed: " << #exp ; \ 00125 wex << "\n" << msg; \ 00126 } \ 00127 } 00128 00129 00130 /// DEPRECATED 00131 #define THROW(exp, msg) ASSERT_THROW(exp, msg) 00132 00133 /// similar macro, but halts (this is handy if you need to flip back 00134 /// and forth between throwing and halting versions). Eventually the 00135 /// standard ASSERT() macro should be replaced with this one. 00136 #define ASSERT2(exp, msg) { \ 00137 if (!(exp)) { \ 00138 std::ostringstream oss; \ 00139 oss << msg; \ 00140 ASSERT( exp , "%s", oss.str().c_str()); \ 00141 } \ 00142 } 00143 00144 00145 #endif // WAVEPACKET_EXCEPTION_H__ 00146