Fix: Headers are now installed.
[libsex.git] / include / libsex / Exception.hxx
blob316ca5c781a3a5c5a00c423b5093a82194e8eeca
1 #ifndef LIBSEX_EXCEPTION_HXX
2 #define LIBSEX_EXCEPTION_HXX
4 #include <exception> // std::exception
5 #include <stdexcept> // std::bad_alloc
6 #include <ostream> // std::ostream
8 namespace libsex {
10 /**
11 * Resembles a generic error, stores a message and
12 * optionally references one previous error (linked list).
14 * The supplied character array must be terminated by a
15 * nullbyte. It will be copied into an internal array
16 * (stored on the stack) that is @ref LENGTH chars long,
17 * until a nullbyte is reached or the internal array is
18 * full.
20 * It is possible create chained exceptions. Since we have
21 * to assume that all exceptions are created on the stack,
22 * the previous exception will be copied to the heap and
23 * the current exception stores a pointer to this copy
24 * (singly linked list).
26 * Hence, it is possible that, while having a chain of
27 * exceptions "bubbling up", a std::bad_alloc is thrown. In
28 * this case, a notice is appended and both std::bad_alloc
29 * and previous exceptions are ignored. Instances that have
30 * already been copied on the heap will be deleted
31 * automatically when the latest exception (on the stack)
32 * gets out of scope (RAII).
34 * Constructors that accept instances of std::string as
35 * error messages have been left out. These strings utilize
36 * the heap which may result in above mentioned "double
37 * fault". Thus, accepting std::string is likely to turn
38 * out to be a pitfall. However, std::string responds to
39 * the message @c c_str by providing a pointer to the
40 * underlying character stringm so this design decision
41 * does not create any problems.
43 * @note For OO error handling you should subclass this
44 * class for every type of error. Inheriting by hand
45 * is tedious, you usally don't want to do this.
46 * There are some efficient macros in @file
47 * macros.hxx.
49 class Exception : public std::exception
51 public:
52 /// Max payload of the internal character string.
53 static const unsigned short LENGTH = 500;
55 /**
56 * Creates an exception.
58 * The specified message is copied into an internal
59 * buffer of @ref LENGTH + 1 (nullbyte) characters
60 * length.
62 Exception(const char* const message) throw();
64 /**
65 * Creates a chained exception.
67 * Both the error message and the previous
68 * exception are copied. While @a message is copied
69 * into an internal buffer, clone() is send to @a
70 * previous which in turn dynamically creates a
71 * shallow copy of itsself on the heap and returns
72 * a pointer to it.
74 * Hence, it is possible that clone() may throw
75 * std::bad_alloc. In that case, a notice is
76 * appended to this message (as long as the
77 * internal buffer contains free fields) and the
78 * instance of std::bad_alloc is swallowed.
80 Exception(
81 const char* const message,
82 const Exception& previous) throw();
84 /// No-op.
85 virtual ~Exception() throw();
87 /**
88 * Writes our message to passed stream.
90 * @exception std::ios_base::failure
91 * may be thrown by stream, if it is
92 * configured to do so.
94 void write(std::ostream& out) const throw(std::ios_base::failure);
96 /**
97 * Writes a backtrace to passed stream.
99 * Messages are delimited by one newline and are
100 * printed in reverse chronological order.
102 * @exception std::ios_base::failure
103 * may be thrown by stream, if it is
104 * configured to do so.
106 void backtrace(std::ostream& out) const throw(std::ios_base::failure);
109 * Clones this exception.
110 * @throws std::bad_alloc on memory shortage.
112 virtual const Exception* clone() const throw(std::bad_alloc);
114 /// Returns a pointer to the internal character string.
115 virtual const char* what() const throw();
117 private:
119 * Copy of message passed to constructor.
121 * Length is @ref Exception::LENGTH plus nullbyte.
123 char _message[LENGTH + 1];
125 /// Pointer to copy of previous exception, or null.
126 const Exception* _previous;
128 /// Used by constructors to initialize _message.
129 void _initMessage(const char* const message);
132 }; // namespace
134 #endif