Scarab  v3.9.4
Project 8 C++ Utility Library
base_exception.hh
Go to the documentation of this file.
1 /*
2  * base_exception.hh
3  *
4  * Created on: Mar 17, 2020
5  * Author: N.S. Oblath
6  */
7 
8 #ifndef SCARAB_BASE_EXCEPTION_HH_
9 #define SCARAB_BASE_EXCEPTION_HH_
10 
11 #include "path.hh"
12 #include "scarab_api.hh"
13 
14 #include <exception>
15 #include <sstream>
16 
17 
18 namespace scarab
19 {
25  class SCARAB_API base_exception : public ::std::exception
26  {
27  public:
28  base_exception() noexcept = default;
29  virtual ~base_exception() noexcept = default;
30 
31  // what() inherited from std::exception
32 
33  virtual const char* where() const noexcept = 0;
34  };
35 
54  template< typename x_derived >
56  {
57  public:
58  typed_exception() noexcept;
59  typed_exception( const std::string& a_filename, int a_line ) noexcept;
60  typed_exception( const typed_exception< x_derived >& a_orig ) noexcept;
61  virtual ~typed_exception() noexcept;
62 
64 
65  template< class x_streamable >
66  x_derived& operator<<( x_streamable a_fragment );
67  x_derived& operator<<( const std::string& a_fragment );
68  x_derived& operator<<( const char* a_fragment );
69 
70  x_derived& operator()( const std::string& a_filename, int a_line );
71 
72  virtual const char* what() const noexcept;
73  virtual const char* where() const noexcept;
74 
75  const std::string& filename() const;
76  int line() const;
77 
78  protected:
79  mutable std::string f_what;
80  mutable std::string f_where;
81 
82  std::string f_filename;
83  int f_line;
84  };
85 
86  template< typename x_derived >
89  f_what(),
90  f_where(),
91  f_filename(),
92  f_line(0)
93  {}
94 
95  template< typename x_derived >
96  typed_exception< x_derived >::typed_exception( const std::string& a_filename, int a_line) noexcept :
98  f_what(),
99  f_where(),
100  f_filename(),
101  f_line( a_line )
102  {
103  try
104  {
105  f_filename = a_filename;
106  }
107  catch( ... )
108  {
109  f_filename.clear();
110  }
111  }
112 
113  template< typename x_derived >
115  base_exception( a_orig ),
116  f_what( a_orig.f_what ),
117  f_where(),
118  f_filename(),
119  f_line( a_orig.f_line )
120  {
121  try
122  {
123  f_filename = a_orig.f_filename;
124  }
125  catch( ... )
126  {
127  f_filename.clear();
128  }
129  }
130 
131  template< typename x_derived >
133  {}
134 
135  template< typename x_derived >
137  {
138  f_what = a_orig.f_error;
139  return *this;
140  }
141 
142  template< typename x_derived >
143  const char* typed_exception< x_derived >::what() const noexcept
144  {
145  return f_what.c_str();
146  }
147 
148  template< typename x_derived >
149  const char* typed_exception< x_derived >::where() const noexcept
150  {
151  try
152  {
153  f_where = path(f_filename).filename().string() + "(" + std::to_string(f_line) + ")";
154  }
155  catch( ... )
156  {
157  f_where.clear();
158  }
159  return f_where.c_str();
160  }
161 
162  template< typename x_derived >
163  template< class x_streamable >
164  x_derived& typed_exception< x_derived >::operator<<( x_streamable a_fragment )
165  {
166  std::stringstream stream;
167  stream << a_fragment;
168  f_what += stream.str();
169  return *static_cast< x_derived* >(this);
170  }
171 
172  template< typename x_derived >
173  x_derived& typed_exception< x_derived >::operator<<( const std::string& a_fragment )
174  {
175  f_what += a_fragment;
176  return *static_cast< x_derived* >(this);
177  }
178 
179  template< typename x_derived >
180  x_derived& typed_exception< x_derived >::operator<<( const char* a_fragment )
181  {
182  f_what += std::string( a_fragment );
183  return *static_cast< x_derived* >(this);
184  }
185 
186  template< typename x_derived >
187  x_derived& typed_exception< x_derived >::operator()( const std::string& a_filename, int a_line )
188  {
189  f_filename = a_filename;
190  f_line = a_line;
191  return *static_cast< x_derived* >(this);
192  }
193 
194  template< typename x_derived >
195  const std::string& typed_exception< x_derived >::filename() const
196  {
197  return f_filename;
198  }
199 
200  template< typename x_derived >
202  {
203  return f_line;
204  }
205 }
206 
207 #endif /* SCARAB_BASE_EXCEPTION_HH_ */
Base class for exceptions with streaming operators and filename/line number location.
fs::path path
Definition: path.hh:26
#define SCARAB_API
Definition: scarab_api.hh:24
virtual const char * what() const noexcept
x_derived & operator()(const std::string &a_filename, int a_line)
x_derived & operator<<(x_streamable a_fragment)
const std::string & filename() const
virtual ~typed_exception() noexcept
SCARAB_API std::ostream & operator<<(std::ostream &out, const param_array &a_value)
Definition: param_array.cc:167
typed_exception< x_derived > & operator=(const typed_exception< x_derived > &a_orig)
virtual const char * where() const noexcept
Base class for exceptions with what() and where() functions.
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: CLI11.hpp:1028