Honeycomb  0.1
Component-Model Framework
Exception.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/String/Stream.h"
5 
6 namespace honey
7 {
8 
10 #ifndef FINAL
11  #define throw_ Exception::Raiser() ^ Exception::Source(__FUNC__, __FILE__, __LINE__) <<
12 #else
13  #define throw_ Exception::Raiser() ^
14 #endif
15 
17 #define EXCEPTION(Class) \
18  typedef SharedPtr<Class> Ptr; \
19  typedef SharedPtr<const Class> ConstPtr; \
20  \
21  virtual Exception::Ptr clone() const { return new Class(*this); } \
22  virtual String typeName() const { return typeid(*this).name(); } \
23  virtual void raise() const { throw *this; } \
24 
25 
27 
45 class Exception : public SharedObj<Exception>, public std::exception
46 {
47 public:
49  struct MsgStream : ostringstream
50  {
51  MsgStream(Exception& e) : e(&e) {}
52  MsgStream(MsgStream&& rhs) : ostringstream(std::move(rhs)), e(rhs.e) { rhs.e = nullptr; }
54  };
55 
57  struct Source
58  {
59  Source() : func(nullptr), file(nullptr), line(0) {}
60  Source(const char* func, const char* file, int line) : func(func), file(file), line(line) {}
61  Exception& operator<<(Exception& e) { e._source = *this; return e; }
62  Exception&& operator<<(Exception&& e) { e._source = *this; return move(e); }
63 
64  friend ostream& operator<<(ostream& os, const Source& source)
65  {
66  return os << c_str(source.func) << ":" << c_str(source.file) << ":" << source.line;
67  }
68 
69  const char* func;
70  const char* file;
71  int line;
72  };
73 
75  struct Raiser
76  {
77  void operator^(const Exception& e) { e.raise(); }
78  void operator^(const ostream& os) { auto& ms = static_cast<const MsgStream&>(os); assert(ms.e); ms.e->_message += ms.str(); ms.e->raise(); }
79  };
80 
81  Exception() = default;
82  Exception(const Exception& rhs) { operator=(rhs); }
83 
85  {
86  _source = rhs._source;
87  _message = rhs._message;
88  _what = nullptr;
89  return *this;
90  }
91 
93 
94 
95  const Source& source() const { return _source; }
97  const String& message() const { return _message; }
98 
100  const char* what() const throw() { cacheWhat(); return _what->c_str(); }
101 
103  static Ptr current();
104 
106  template<class T>
107  MsgStream operator<<(T&& val) { return forward<MsgStream>(MsgStream(*this) << std::forward<T>(val)); }
108 
109  friend ostream& operator<<(ostream& os, const Exception& e) { return os << e.what(); }
110 
111 protected:
113  virtual String createWhat() const
114  {
115  return source().func ?
116  sout() << message() << " (exception: " << typeName() << "; " << source() << ")" :
117  sout() << message();
118  }
119 
120 private:
121  void cacheWhat() const { if (!_what) _what = honey::make_unique<std::string>(createWhat()); }
122 
123  Source _source;
124  String _message;
125  mutable UniquePtr<std::string> _what;
126 };
127 
129 namespace exception
130 {
132  template<class T>
133  struct Std : Exception
134  {
137 
138  Std(const T& e) : _e(e) { *this << _e.what(); }
139 
140  virtual Exception::Ptr clone() const { return new Std(_e); }
141  virtual String typeName() const { return typeid(_e).name(); }
142  virtual void raise() const { throw _e; }
143 
144  private:
145  T _e;
146  };
147 
148  template<class T>
149  typename Std<T>::Ptr createStd(const T& e) { return new Std<T>(e); }
150 
152 }
153 
154 inline Exception::Ptr Exception::current()
155 {
156  //std exceptions are not dynamic so there's no way to clone them trivially
157  try { throw; }
158  catch (Exception& e) { return e.clone(); }
159  catch (std::domain_error& e) { return honey::exception::createStd(e); }
160  catch (std::invalid_argument& e) { return honey::exception::createStd(e); }
161  catch (std::length_error& e) { return honey::exception::createStd(e); }
162  catch (std::out_of_range& e) { return honey::exception::createStd(e); }
163  catch (std::logic_error& e) { return honey::exception::createStd(e); }
164  catch (std::range_error& e) { return honey::exception::createStd(e); }
165  catch (std::overflow_error& e) { return honey::exception::createStd(e); }
166  catch (std::underflow_error& e) { return honey::exception::createStd(e); }
167  catch (std::ios_base::failure& e) { return honey::exception::createStd(e); }
168  catch (std::runtime_error& e) { return honey::exception::createStd(e); }
169  catch (std::bad_alloc& e) { return honey::exception::createStd(e); }
170  catch (std::bad_cast& e) { return honey::exception::createStd(e); }
171  catch (std::bad_typeid& e) { return honey::exception::createStd(e); }
172  catch (std::bad_exception& e) { return honey::exception::createStd(e); }
173  catch (std::exception& e) { return honey::exception::createStd(e); }
174  catch (...) { return new honey::exception::Unknown(); }
175 }
176 
177 namespace debug
178 {
181 }
182 
183 }
184 
int line
Definition: Exception.h:71
SharedPtr< Std > Ptr
Definition: Exception.h:135
Thrown on debug assert() failure.
Definition: Exception.h:180
const char * file
Definition: Exception.h:70
Combined intrusive/non-intrusive smart pointer. Can reference and share any object automatically...
Definition: SharedPtr.h:175
Std< T >::Ptr createStd(const T &e)
Definition: Exception.h:149
Level debug(nullptr,"debug")
Low-level information for debugging purposes.
Definition: Log.h:26
STL namespace.
const Char * c_str(const Char *str)
Ensures that str points to a valid C-string. If str is null then the result is an empty C-string (ie...
Definition: String.h:159
Info about source where exception was thrown.
Definition: Exception.h:57
Source()
Definition: Exception.h:59
Reference-counted object for intrusive shared pointers.
Definition: SharedPtr.h:93
virtual Exception::Ptr clone() const
Definition: Exception.h:140
friend ostream & operator<<(ostream &os, const Exception &e)
Definition: Exception.h:109
Definition: Exception.h:151
Wrapper around std exception to allow for polymorphic throw.
Definition: Exception.h:133
#define EXCEPTION(Class)
Declares methods required for every subclass of honey::Exception.
Definition: Exception.h:17
Exception()=default
Exception(const Exception &rhs)
Definition: Exception.h:82
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
const Source & source() const
Get info about source where exception was thrown.
Definition: Exception.h:95
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
friend ostream & operator<<(ostream &os, const Source &source)
Definition: Exception.h:64
Unicode UTF-16 string class, wrapper around std::u16string.
Definition: String.h:23
Exception * e
Definition: Exception.h:53
Base exception class. Exceptions inherited from this class provide debug info and can be thrown polym...
Definition: Exception.h:45
void operator^(const Exception &e)
Definition: Exception.h:77
MsgStream(MsgStream &&rhs)
Definition: Exception.h:52
virtual String typeName() const
Definition: Exception.h:141
const String & message() const
Get custom error message. The error message can be appended to using global operator<<(Exception, String)
Definition: Exception.h:97
Exception & operator<<(Exception &e)
Definition: Exception.h:61
void operator^(const ostream &os)
Definition: Exception.h:78
MsgStream(Exception &e)
Definition: Exception.h:51
Exception & operator=(const Exception &rhs)
Definition: Exception.h:84
const char * func
Definition: Exception.h:69
Std(const T &e)
Definition: Exception.h:138
static Ptr current()
Create a clone of the current exception caught with (...)
Definition: Exception.h:154
MsgStream operator<<(T &&val)
Append custom error message.
Definition: Exception.h:107
Helper to raise an exception after the right side of ^ has been evaluated.
Definition: Exception.h:75
Global Honeycomb namespace.
SharedPtr< const Std > ConstPtr
Definition: Exception.h:136
Custom error message builder.
Definition: Exception.h:49
Exception && operator<<(Exception &&e)
Definition: Exception.h:62
virtual String createWhat() const
Create what message. Called only on demand and result is cached.
Definition: Exception.h:113
const char * what() const
Get full diagnostic message.
Definition: Exception.h:100
Source(const char *func, const char *file, int line)
Definition: Exception.h:60