1 //  Copyright (c) 2007-2013 Hartmut Kaiser
2 //  Copyright (c) 2011      Bryce Lelbach
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 /// \file throw_exception.hpp
8 
9 #ifndef HPX_THROW_EXCEPTION_HPP
10 #define HPX_THROW_EXCEPTION_HPP
11 
12 #include <hpx/config.hpp>
13 #include <hpx/error.hpp>
14 #include <hpx/exception_fwd.hpp>
15 #include <hpx/util/detail/pp/cat.hpp>
16 #include <hpx/util/detail/pp/expand.hpp>
17 #include <hpx/util/detail/pp/nargs.hpp>
18 
19 #include <boost/current_function.hpp>
20 #include <boost/system/error_code.hpp>
21 
22 #include <exception>
23 #include <string>
24 
25 #include <hpx/config/warnings_prefix.hpp>
26 
27 /// \cond NODETAIL
28 namespace hpx { namespace detail
29 {
30     template <typename Exception>
31     HPX_NORETURN HPX_EXPORT
32     void throw_exception(Exception const& e,
33         std::string const& func, std::string const& file, long line);
34 
35     HPX_NORETURN HPX_EXPORT void throw_exception(
36         error errcode, std::string const& msg,
37         std::string const& func, std::string const& file, long line);
38 
39     HPX_NORETURN HPX_EXPORT void rethrow_exception(
40         exception const& e, std::string const& func);
41 
42     template <typename Exception>
43     HPX_EXPORT std::exception_ptr get_exception(Exception const& e,
44             std::string const& func = "<unknown>",
45             std::string const& file = "<unknown>",
46             long line = -1,
47             std::string const& auxinfo = "");
48 
49     HPX_EXPORT std::exception_ptr get_exception(
50             error errcode, std::string const& msg, throwmode mode,
51             std::string const& func = "<unknown>",
52             std::string const& file = "<unknown>",
53             long line = -1,
54             std::string const& auxinfo = "");
55 
56     HPX_EXPORT std::exception_ptr get_exception(
57             boost::system::error_code ec, std::string const& msg, throwmode mode,
58             std::string const& func = "<unknown>",
59             std::string const& file = "<unknown>",
60             long line = -1,
61             std::string const& auxinfo = "");
62 
63     HPX_EXPORT void throws_if(
64         hpx::error_code& ec, error errcode, std::string const& msg,
65         std::string const& func, std::string const& file, long line);
66 
67     HPX_EXPORT void rethrows_if(
68         hpx::error_code& ec, exception const& e, std::string const& func);
69 
70     HPX_NORETURN HPX_EXPORT
71     void throw_thread_interrupted_exception();
72 }}
73 /// \endcond
74 
75 namespace hpx
76 {
77     /// \cond NOINTERNAL
78 
79     /// \brief throw an hpx::exception initialized from the given arguments
80     HPX_NORETURN inline
throw_exception(error e,std::string const & msg,std::string const & func,std::string const & file="",long line=-1)81     void throw_exception(error e, std::string const& msg,
82         std::string const& func, std::string const& file = "", long line = -1)
83     {
84         detail::throw_exception(e, msg, func, file, line);
85     }
86     /// \endcond
87 }
88 
89 /// \cond NOINTERNAL
90 ///////////////////////////////////////////////////////////////////////////////
91 // helper macro allowing to prepend file name and line number to a generated
92 // exception
93 #define HPX_THROW_STD_EXCEPTION(except, func)                                 \
94     hpx::detail::throw_exception(except, func, __FILE__, __LINE__)            \
95     /**/
96 
97 #define HPX_RETHROW_EXCEPTION(e, f)                                           \
98     hpx::detail::rethrow_exception(e, f)                                      \
99     /**/
100 
101 #define HPX_RETHROWS_IF(ec, e, f)                                             \
102     hpx::detail::rethrows_if(ec, e, f)                                        \
103     /**/
104 
105 ///////////////////////////////////////////////////////////////////////////////
106 #define HPX_GET_EXCEPTION(...)                                                \
107     HPX_GET_EXCEPTION_(__VA_ARGS__)                                           \
108 /**/
109 
110 #define HPX_GET_EXCEPTION_(...)                                               \
111     HPX_PP_EXPAND(HPX_PP_CAT(                                                 \
112         HPX_GET_EXCEPTION_, HPX_PP_NARGS(__VA_ARGS__)                         \
113     )(__VA_ARGS__))                                                           \
114 /**/
115 #define HPX_GET_EXCEPTION_3(errcode, f, msg)                                  \
116     HPX_GET_EXCEPTION_4(errcode, hpx::plain, f, msg)                          \
117 /**/
118 #define HPX_GET_EXCEPTION_4(errcode, mode, f, msg)                            \
119     hpx::detail::get_exception(errcode, msg, mode, f,                         \
120         __FILE__, __LINE__)                                                   \
121 /**/
122 
123 ///////////////////////////////////////////////////////////////////////////////
124 #define HPX_THROW_IN_CURRENT_FUNC(errcode, msg)                               \
125     HPX_THROW_EXCEPTION(errcode, BOOST_CURRENT_FUNCTION, msg)                 \
126     /**/
127 
128 #define HPX_RETHROW_IN_CURRENT_FUNC(errcode, msg)                             \
129     HPX_RETHROW_EXCEPTION(errcode, BOOST_CURRENT_FUNCTION, msg)               \
130     /**/
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 #define HPX_THROWS_IN_CURRENT_FUNC_IF(ec, errcode, msg)                       \
134     HPX_THROWS_IF(ec, errcode, BOOST_CURRENT_FUNCTION, msg)                   \
135     /**/
136 
137 #define HPX_RETHROWS_IN_CURRENT_FUNC_IF(ec, errcode, msg)                     \
138     HPX_RETHROWS_IF(ec, errcode, BOOST_CURRENT_FUNCTION, msg)                 \
139     /**/
140 
141 ///////////////////////////////////////////////////////////////////////////////
142 #define HPX_THROW_THREAD_INTERRUPTED_EXCEPTION()                              \
143     hpx::detail::throw_thread_interrupted_exception()                         \
144     /**/
145 /// \endcond
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 /// \def HPX_THROW_EXCEPTION(errcode, f, msg)
149 /// \brief Throw a hpx::exception initialized from the given parameters
150 ///
151 /// The macro \a HPX_THROW_EXCEPTION can be used to throw a hpx::exception.
152 /// The purpose of this macro is to prepend the source file name and line number
153 /// of the position where the exception is thrown to the error message.
154 /// Moreover, this associates additional diagnostic information with the
155 /// exception, such as file name and line number, locality id and thread id,
156 /// and stack backtrace from the point where the exception was thrown.
157 ///
158 /// The parameter \p errcode holds the hpx::error code the new exception should
159 /// encapsulate. The parameter \p f is expected to hold the name of the
160 /// function exception is thrown from and the parameter \p msg holds the error
161 /// message the new exception should encapsulate.
162 ///
163 /// \par Example:
164 ///
165 /// \code
166 ///      void raise_exception()
167 ///      {
168 ///          // Throw a hpx::exception initialized from the given parameters.
169 ///          // Additionally associate with this exception some detailed
170 ///          // diagnostic information about the throw-site.
171 ///          HPX_THROW_EXCEPTION(hpx::no_success, "raise_exception", "simulated error");
172 ///      }
173 /// \endcode
174 ///
175 #define HPX_THROW_EXCEPTION(errcode, f, msg)                                  \
176     hpx::detail::throw_exception(errcode, msg, f, __FILE__, __LINE__)         \
177     /**/
178 
179 /// \def HPX_THROWS_IF(ec, errcode, f, msg)
180 /// \brief Either throw a hpx::exception or initialize \a hpx::error_code from
181 ///        the given parameters
182 ///
183 /// The macro \a HPX_THROWS_IF can be used to either throw a \a hpx::exception
184 /// or to initialize a \a hpx::error_code from the given parameters. If
185 /// &ec == &hpx::throws, the semantics of this macro are equivalent to
186 /// \a HPX_THROW_EXCEPTION. If &ec != &hpx::throws, the \a hpx::error_code
187 /// instance \p ec is initialized instead.
188 ///
189 /// The parameter \p errcode holds the hpx::error code from which the new
190 /// exception should be initialized. The parameter \p f is expected to hold the
191 /// name of the function exception is thrown from and the parameter \p msg
192 /// holds the error message the new exception should encapsulate.
193 ///
194 #define HPX_THROWS_IF(ec, errcode, f, msg)                                    \
195     hpx::detail::throws_if(ec, errcode, msg, f, __FILE__, __LINE__)           \
196     /**/
197 
198 #include <hpx/config/warnings_suffix.hpp>
199 
200 #endif
201