Library of Assembled Shared Sources
util/exception.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2023 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45/** @class lass::util::Exception
46 * @brief type of all exceptions in lass
47 * @author Bram de Greve [Bramz]
48 *
49 * @sa LASS_THROW
50 */
51
52#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_EXCEPTION_H
53#define LASS_GUARDIAN_OF_INCLUSION_UTIL_EXCEPTION_H
54
55#include "util_common.h"
56#include <exception>
57#include <string>
58#include <sstream>
59
60namespace lass
61{
62namespace util
63{
64
65class RemoteExceptionBase;
66
67typedef std::unique_ptr<RemoteExceptionBase> TRemoteExceptionBasePtr;
68
69class LASS_DLL RemoteExceptionBase
70{
71public:
72 virtual ~RemoteExceptionBase();
73 void throwSelf() const;
74 TRemoteExceptionBasePtr clone() const;
75
76private:
77 virtual void doThrowSelf() const = 0;
78 virtual RemoteExceptionBase* doClone() const = 0;
79};
80
81
82class Exception: public std::exception, public RemoteExceptionBase
83{
84public:
85 Exception(std::string message, std::string location):
86 message_(std::move(message)),
87 location_(std::move(location))
88 {
89 }
90 explicit Exception(std::string message):
91 Exception(std::move(message), std::string())
92 {
93 }
94 Exception():
95 Exception(std::string(), std::string())
96 {
97 }
98 ~Exception() noexcept {}
99 const char* what() const noexcept override { return message_.c_str(); }
100 const std::string& message() const { return message_; }
101 const std::string& location() const { return location_; }
102private:
103 std::string message_;
104 std::string location_;
105 void doThrowSelf() const override { throw *this; }
106 RemoteExceptionBase* doClone() const override { return new Exception(*this); }
107};
108
109
110
111template <typename ExceptionType, typename ParentType = Exception>
112class ExceptionMixin: public ParentType
113{
114public:
115 ExceptionMixin(std::string message, std::string location):
116 ParentType(std::move(message), std::move(location))
117 {
118 }
119 explicit ExceptionMixin(std::string message):
120 ParentType(std::move(message))
121 {
122 }
123 ~ExceptionMixin() noexcept {}
124private:
125 virtual void doThrowSelf() const override
126 {
127 throw *static_cast<const ExceptionType*>(this);
128 }
129 virtual RemoteExceptionBase* doClone() const override
130 {
131 return new ExceptionType(*static_cast<const ExceptionType*>(this));
132 }
133};
134
135
136
137template <typename LocalException>
138class RemoteExceptionWrapper:
139 public virtual LocalException,
140 public virtual RemoteExceptionBase
141{
142public:
143 RemoteExceptionWrapper(const LocalException& e): LocalException(e) {}
144 ~RemoteExceptionWrapper() noexcept {}
145private:
146 void doThrowSelf() const override
147 {
148 throw *this;
149 }
150 RemoteExceptionBase* doClone() const override
151 {
152 typedef RemoteExceptionWrapper<LocalException> TSelf;
153 return new TSelf(*static_cast<const LocalException*>(this));
154 }
155};
156
157
158
159class KeyError: public ExceptionMixin<KeyError>
160{
161public:
162 KeyError(std::string msg, std::string loc): ExceptionMixin<KeyError>(std::move(msg), std::move(loc)) {}
163 ~KeyError() noexcept {}
164};
165
166
167class ValueError: public ExceptionMixin<ValueError>
168{
169public:
170 ValueError(std::string msg, std::string loc) : ExceptionMixin<ValueError>(std::move(msg), std::move(loc)) {}
171 ~ValueError() noexcept {}
172};
173
174class SingularityError: public ExceptionMixin<SingularityError>
175{
176public:
177 SingularityError(std::string msg, std::string loc) : ExceptionMixin<SingularityError>(std::move(msg), std::move(loc)) {}
178 ~SingularityError() noexcept {}
179};
180
181}
182
183}
184
185/** @relates lass::util::Exception
186 *
187 * To throw an exception like util::Exception that accepts a message and a location string, you
188 * can supply those strings yourself, ore you can use this macro for your convenience.
189 *
190 * This macro will fill in the location by itself so that you only have to worry about the message.
191 * And as an extra, the message is streamed, so you can use the regular @c operator<< to
192 * concatenate variables in the message.
193 *
194 * @code
195 * int foo = -5;
196 * if (foo < 0)
197 * {
198 * LASS_THROW_EX(util::Exception, "foo '" << foo << "' is less than zero");
199 * }
200 * @endcode
201 */
202#define LASS_THROW_EX(t_exception, s_message)\
203 do\
204 {\
205 ::std::ostringstream lassUtilExceptionImplBuffer;\
206 lassUtilExceptionImplBuffer << s_message;\
207 throw t_exception(lassUtilExceptionImplBuffer.str(), LASS_PRETTY_FUNCTION);\
208 }\
209 while (false)
210
211
212
213/** LASS_THROW_EX for ::lass::util::Exception
214 * @relates lass::Util::Exception
215 *
216 * LASS_THROW(something) is identical to LASS_THROW_EX(util::Exception, something)
217 */
218#define LASS_THROW(s_message) LASS_THROW_EX(::lass::util::Exception, s_message)
219
220
221
222/** @relates lass::Util::Exception
223 *
224 * catches all exceptions and prints an undefined behaviour warning to std::cerr
225 */
226#define LASS_CATCH_TO_WARNING\
227 catch (const ::std::exception& error)\
228 {\
229 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: Exception caught in "\
230 << LASS_PRETTY_FUNCTION << ":\n" << error.what() << std::endl;\
231 }\
232 catch (...)\
233 {\
234 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: Unknown exception caught in "\
235 << LASS_PRETTY_FUNCTION << std::endl;\
236 }\
237 /**/
238
239#endif
240
241// EOF
#define LASS_DLL
DLL interface: import or export symbols?
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53