libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
exception.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_EXCEPTION_HPP
2 #define LIBJMMCG_CORE_EXCEPTION_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "exit_codes.hpp"
23 #include "info.hpp"
25 
26 #ifdef WIN32
27 # include "thread_api_traits.hpp"
28 #endif
29 
30 #include <boost/iostreams/stream.hpp>
31 
32 #include <array>
33 #include <cerrno>
34 #include <stdexcept>
35 #include <cstring>
36 
37 #ifdef __GCC__
38 # pragma GCC diagnostic push
39 # pragma GCC diagnostic ignored "-Wsuggest-final-methods"
40 #endif
41 
42 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
43 
44  namespace ppd {
45  template<generic_traits::api_type API, typename Mdl>
46  struct api_threading_traits;
47  }
48 
49 /// Handy for use in source files.
50 #define JMMCG_MAKE_EXCPT_SRC1(_JMMCG_EXCPT_MSG) jmmcg::LIBJMMCG_VER_NAMESPACE::exception((_JMMCG_EXCPT_MSG), JMMCG_FUNCTION(void), __REV_INFO__)
51 /// Handy for use in header files.
52 #define JMMCG_MAKE_EXCPT_HDR1(_JMMCG_EXCPT_MSG,_JMMCG_REVISION_HDR) jmmcg::LIBJMMCG_VER_NAMESPACE::exception((_JMMCG_EXCPT_MSG), JMMCG_FUNCTION(void), JMMCG_REVISION(_JMMCG_REVISION_HDR))
53 /// Handy for use in source files.
54 #define JMMCG_MAKE_CEXCPT_SRC1(_JMMCG_EXCPT_MSG) jmmcg::LIBJMMCG_VER_NAMESPACE::crt_exception((_JMMCG_EXCPT_MSG), JMMCG_FUNCTION(void), __REV_INFO__)
55 /// Handy for use in header files.
56 #define JMMCG_MAKE_CEXCPT_HDR1(_JMMCG_EXCPT_MSG,_JMMCG_REVISION_HDR) jmmcg::LIBJMMCG_VER_NAMESPACE::crt_exception((_JMMCG_EXCPT_MSG), JMMCG_FUNCTION(void), JMMCG_REVISION(_JMMCG_REVISION_HDR))
57 
58  /**
59  Inheritance from "std::runtime_error" is done in case of object slicing (which can occur with exceptions) so I set the error string in the exception as best I can. Note that for derived exception classes, the error string held n "std::exception" may not have everything in it compared to the overrriden "what()". But it is better than sweet f.a.
60  */
61  template<ppd::generic_traits::api_type API, typename Mdl>
62  class exception : public std::runtime_error {
63  public:
64  typedef std::runtime_error base_t;
65  typedef ppd::api_threading_traits<API, Mdl> thread_traits;
67 
68  exception(tstring &&r, info::function &&f, info::revision &&ri) noexcept(false);
69  exception(const tostringstream &r, info::function &&f, info::revision &&ri) noexcept(false);
70  exception(const exception &ex) noexcept(false);
71  void operator=(exception const &)=delete;
72  void operator=(exception &&)=delete;
73  virtual ~exception() noexcept(true) {
74  }
75 
76  virtual exit_codes::codes __fastcall
77  code() const noexcept(true) {
79  }
80 
81  char const * __CLR_OR_THIS_CALL what() const noexcept(true) final override;
82 
83  virtual const tstring __fastcall to_string() const noexcept(false);
84 
85  static constexpr std::size_t max_size() noexcept(true) {
86  return 27+PATH_MAX+3
88  +14+std::numeric_limits<std::size_t>::digits10
89  +29+std::numeric_limits<std::size_t>::digits10
90  +13+32+1
91  +1+sizeof(LIBJMMCG_DETAILED_VERSION_INFO)+1;
92  }
93 
94  /**
95  \todo Implement using the advice given in "Standard C++ IOStreams and Locales" by A.Langer & K.Kreft, page 170.
96  */
97  friend tostream & __fastcall
98  operator<<(tostream &o, const exception &e) noexcept(false) {
99  return o<<e.to_string();
100  }
101 
102  protected:
106 
107  private:
108  const tstring reason;
109  const info::function func;
110  const info::revision rev;
111  mutable std::string what_;
112 
113  static NEVER_INLINE const tstring __fastcall
114  to_string(const tstring &r, const info::function &f, const info::revision &rev, const typename thread_traits::api_params_type::pid_type pid, const typename thread_traits::api_params_type::tid_type tid, typename thread_traits::api_params_type::username_type const &uname) noexcept(false) {
115  std::array<tchar, max_size()> buff;
116  boost::iostreams::stream<boost::iostreams::array_sink> o(buff.data(), buff.max_size());
117  o<<_T("Exception thrown. Reason: '")<<r<<_T("'.\n")
118  <<f<<rev
119  <<_T("Process ID: 0x")<<std::hex<<pid
120  <<_T(", thread ID: 0x")<<std::hex<<tid
121  <<_T(", username: '")<<uname.data()<<_T("'\n")
123  return tstring{buff.data()};
124  }
125  };
126 
127  const tstring __fastcall
128  dump_crt_errno(const unsigned long err=errno) noexcept(false);
129 
130  template<ppd::generic_traits::api_type API, typename Mdl>
131  class crt_exception : public exception<API, Mdl> {
132  public:
133  using base_t=exception<API, Mdl>;
134  using thread_traits=typename base_t::thread_traits;
135 
136  crt_exception(tstring &&r, info::function &&f, info::revision &&ri, const unsigned long en=errno) noexcept(false);
137  crt_exception(const tostringstream &r, info::function &&f, info::revision &&ri, const unsigned long en=errno) noexcept(false);
138  crt_exception(const crt_exception &ex) noexcept(false);
139  void operator=(crt_exception const &)=delete;
140  void operator=(crt_exception &&)=delete;
141  virtual ~crt_exception() noexcept(true) {
142  }
143 
144  exit_codes::codes __fastcall
145  code() const noexcept(true) override {
147  }
148 
149  const tstring __fastcall to_string() const noexcept(false) override;
150 
151  static constexpr std::size_t max_size() noexcept(true) {
152  return base_t::max_size()+14+std::numeric_limits<std::size_t>::digits10+23+1024+4;
153  }
154 
155  /**
156  \todo Implement using the advice given in "Standard C++ IOStreams and Locales" by A.Langer & K.Kreft, page 170.
157  */
158  friend tostream & __fastcall
159  operator<<(tostream &o, const crt_exception &e) noexcept(false) {
160  return o<<e.to_string();
161  }
162 
163  private:
164  const unsigned long crt_errno;
165  };
166 
167 } }
168 
169 #ifdef WIN32
170 # include "../experimental/NT-based/NTSpecific/exception.hpp"
171 #endif
172 
173 #include "exception_impl.hpp"
174 
175 #ifdef __GCC__
176 # pragma GCC diagnostic pop
177 #endif
178 
179 #endif