|
libpsynth 0.2.1
|
00001 00015 /* 00016 * Copyright (C) 2011 Juan Pedro BolĂvar Puente 00017 * 00018 * This file is part of Psychosynth. 00019 * 00020 * Psychosynth is free software: you can redistribute it and/or modify 00021 * it under the terms of the GNU General Public License as published by 00022 * the Free Software Foundation, either version 3 of the License, or 00023 * (at your option) any later version. 00024 * 00025 * Psychosynth is distributed in the hope that it will be useful, 00026 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00027 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00028 * GNU General Public License for more details. 00029 * 00030 * You should have received a copy of the GNU General Public License 00031 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00032 * 00033 */ 00034 00035 #ifndef PSYNTH_BASE_THROW_HPP_ 00036 #define PSYNTH_BASE_THROW_HPP_ 00037 00038 #include <psynth/base/logger.hpp> 00039 #include <psynth/base/exception.hpp> 00040 00041 namespace psynth 00042 { 00043 namespace base 00044 { 00045 00046 namespace detail 00047 { 00048 00049 template <class Base, bool IsPsynth> 00050 class exception_wrapper : public virtual Base 00051 { 00052 public: 00053 exception_wrapper (const char* where) 00054 : _where (where) 00055 , _stream (logger::self ().path (where)) 00056 { 00057 _stream.set_level (Base::level ()); 00058 } 00059 00060 exception_wrapper (const exception_wrapper&) = default; 00061 exception_wrapper (exception_wrapper&&) = default; 00062 exception_wrapper& operator= (const exception_wrapper&) = default; 00063 00064 ~exception_wrapper () throw () {} 00065 00066 const char* where () const throw () 00067 { return _where; } 00068 00069 const char* what () const throw () 00070 { return _stream.message ().c_str (); } 00071 00072 int level () const throw () 00073 { return _stream.level (); } 00074 00075 log_stream_adapter& stream () 00076 { return _stream; } 00077 00078 private: 00079 const char* _where; 00080 log_stream_adapter _stream; 00081 }; 00082 00083 template <class Base> 00084 class exception_wrapper<Base, false> : public virtual Base 00085 , public virtual exception 00086 { 00087 public: 00088 exception_wrapper (const char* where) 00089 : Base ("") // HACK: This allows throwing logic_error etc, but 00090 // forbidds raw std::exception and others. 00091 , _where (where) 00092 , _stream (logger::self ().path (where)) 00093 { 00094 _stream.set_level (default_error_level ()); 00095 } 00096 00097 exception_wrapper (const exception_wrapper&) = default; 00098 exception_wrapper (exception_wrapper&&) = default; 00099 exception_wrapper& operator= (const exception_wrapper&) = default; 00100 00101 ~exception_wrapper () throw () {} 00102 00103 const char* what () const throw () 00104 { return _stream.message ().c_str (); } 00105 00106 const char* where () const throw () 00107 { return _where; } 00108 00109 int level () const throw () 00110 { return _stream.level (); } 00111 00112 log_stream_adapter& stream () 00113 { return _stream; } 00114 00115 private: 00116 const char* _where; 00117 log_stream_adapter _stream; 00118 }; 00119 00120 } /* namespace detail */ 00121 00122 template <class Exception> 00123 class throw_with : public boost::noncopyable 00124 { 00125 public: 00126 explicit throw_with (const char* where = "") 00127 : _exception (where) 00128 , _owner (false) 00129 {} 00130 00131 throw_with (throw_with&& other) 00132 : _exception (std::move (other._exception)) 00133 , _owner (true) 00134 { 00135 other._owner = false; 00136 } 00137 00138 ~throw_with () 00139 { 00140 if (_owner) 00141 throw _exception; 00142 } 00143 00144 private: 00145 template <class E, typename T> 00146 friend throw_with<E> operator<< (throw_with<E>, const T&); 00147 00148 typedef detail::exception_wrapper< 00149 Exception, 00150 std::is_base_of<exception, Exception>::value > 00151 exception_type; 00152 00153 exception_type _exception; 00154 bool _owner; 00155 }; 00156 00157 template <class E, typename T> 00158 throw_with<E> operator<< (throw_with<E> ts, const T& what) 00159 { 00160 ts._exception.stream () << what; 00161 return std::move (ts); 00162 } 00163 00164 #define PSYNTH_THROW(exception) \ 00165 ::psynth::base::throw_with<exception> (PSYNTH_MODULE_NAME) 00166 00167 00168 } /* namespace base */ 00169 } /* namespace psynth */ 00170 00171 #endif /* PSYNTH_BASE_THROW_HPP_ */ 00172 00173
1.7.4