2019-01-08 16:09:25 +01:00
|
|
|
// Copyright 2004, Ondra Kamenik
|
|
|
|
|
|
|
|
// Exception.
|
|
|
|
|
|
|
|
/* Within the code we often check some state of variables, typically
|
|
|
|
preconditions or postconditions. If the state is not as required, it
|
|
|
|
is worthless to continue, since this means some fatal error in
|
|
|
|
algorithms. In this case we raise an exception which can be caught at
|
|
|
|
some higher level. This header file defines a simple infrastructure
|
|
|
|
for this. */
|
|
|
|
|
|
|
|
#ifndef TL_EXCEPTION_H
|
|
|
|
#define TL_EXCEPTION_H
|
|
|
|
|
2019-02-20 17:23:37 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <utility>
|
|
|
|
#include <string>
|
2019-01-08 16:09:25 +01:00
|
|
|
|
|
|
|
/* The basic idea of raising an exception if some condition fails is
|
|
|
|
that the conditions is checked only if required. We define global
|
|
|
|
|TL_DEBUG| macro which is integer and says, how many debug messages
|
|
|
|
the programm has to emit. We also define |TL_DEBUG_EXCEPTION| which
|
|
|
|
says, for what values of |TL_DEBUG| we will check for conditions of
|
|
|
|
the exceptions. If the |TL_DEBUG| is equal or higher than
|
|
|
|
|TL_DEBUG_EXCEPTION|, the exception conditions are checked.
|
|
|
|
|
|
|
|
We define |TL_RAISE|, and |TL_RAISE_IF| macros which throw an instance
|
|
|
|
of |TLException| if |TL_DEBUG >= TL_DEBUG_EXCEPTION|. The first is
|
|
|
|
unconditional throw, the second is conditioned by a given
|
|
|
|
expression. Note that if |TL_DEBUG < TL_DEBUG_EXCEPTION| then the code
|
|
|
|
is compiled but evaluation of the condition is passed. If code is
|
|
|
|
optimized, the optimizer also passes evaluation of |TL_DEBUG| and
|
|
|
|
|TL_DEBUG_EXCEPTION| comparison (I hope).
|
|
|
|
|
|
|
|
We provide default values for |TL_DEBUG| and |TL_DEBUG_EXCEPTION|. */
|
|
|
|
|
|
|
|
#ifndef TL_DEBUG_EXCEPTION
|
|
|
|
# define TL_DEBUG_EXCEPTION 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef TL_DEBUG
|
|
|
|
# define TL_DEBUG 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define TL_RAISE(mes) \
|
|
|
|
if (TL_DEBUG >= TL_DEBUG_EXCEPTION) throw TLException(__FILE__, __LINE__, mes);
|
|
|
|
|
|
|
|
#define TL_RAISE_IF(expr, mes) \
|
|
|
|
if (TL_DEBUG >= TL_DEBUG_EXCEPTION && (expr)) throw TLException(__FILE__, __LINE__, mes);
|
|
|
|
|
|
|
|
/* Primitive exception class containing file name, line number and message. */
|
|
|
|
|
|
|
|
class TLException
|
|
|
|
{
|
2019-02-20 17:23:37 +01:00
|
|
|
const std::string fname;
|
2019-01-08 16:09:25 +01:00
|
|
|
int lnum;
|
2019-02-20 17:23:37 +01:00
|
|
|
const std::string message;
|
2019-01-08 16:09:25 +01:00
|
|
|
public:
|
2019-02-20 17:23:37 +01:00
|
|
|
TLException(std::string fname_arg, int lnum_arg, std::string message_arg)
|
|
|
|
: fname{std::move(fname_arg)},
|
|
|
|
lnum{lnum_arg},
|
|
|
|
message{std::move(message_arg)}
|
2019-01-08 16:09:25 +01:00
|
|
|
{
|
|
|
|
}
|
2019-02-20 17:23:37 +01:00
|
|
|
virtual ~TLException() = default;
|
2019-01-08 16:09:25 +01:00
|
|
|
virtual void
|
|
|
|
print() const
|
|
|
|
{
|
2019-02-20 17:23:37 +01:00
|
|
|
std::cout << "At " << fname << ':' << lnum << ':' << message << std::endl;
|
2019-01-08 16:09:25 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|