wave_ex.h

Go to the documentation of this file.
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