4 #include <boost/stacktrace.hpp>
5 #include <fmt/format.h>
6 #include <fmt/ostream.h>
7 #include <tl/expected.hpp>
35 boost::stacktrace::stacktrace{});
51 std::string
const& message,
56 boost::stacktrace::stacktrace{});
64 std::string
const& message,
69 boost::stacktrace::stacktrace{});
74 template <
class TWrapper,
class TException>
81 std::string msg) -> decltype(*std::forward<TWrapper>(wrapper)) {
83 throw TException(msg, file, line, func);
85 return *std::forward<TWrapper>(wrapper);
91 template <
class TT,
class TE,
class TException>
93 template <
class TExpected>
99 std::string msg) -> decltype(*std::forward<TExpected>(expected)) {
100 if (!
bool(expected)) {
101 msg += fmt::format(
"\nUnexpected: {}", expected.error());
102 throw TException(msg, file, line, func);
104 return *std::forward<TExpected>(expected);
108 template <
class TT,
class TE,
class TException>
110 :
UnwrapImpl<tl::expected<TT, TE>, TException> {};
112 template <
class TT,
class TE,
class TException>
114 :
UnwrapImpl<tl::expected<TT, TE>, TException> {};
116 template <
class TT,
class TE,
class TException>
118 :
UnwrapImpl<tl::expected<TT, TE>, TException> {};
120 template <
class TContainer,
class TKey,
class TException>
122 TContainer& container,
124 char const* container_cstr,
125 char const* key_cstr,
129 std::string msg) -> decltype(*(container.find(key))) {
130 auto it = container.find(key);
131 if (it == container.end()) {
133 "SOL3_GET key `{}` (={}) not in associative container `{}` of "
140 throw TException(msg, file, line, func);
146 template <
class TContainer,
class TException>
148 TContainer& container,
150 char const* container_cstr,
151 char const* index_cstr,
155 std::string msg) -> decltype(container[index]) {
156 if (index >= container.size()) {
158 "SOL3_AT index `{}` (={}) not in contiguous container `{}` of "
165 throw TException(msg, file, line, func);
167 return container[index];
177 #define SOL3_THROW(TException, ...) \
179 ::fmt::format(__VA_ARGS__), \
182 (char const*)(__PRETTY_FUNCTION__))
198 #define SOL3_UNWRAP_OR_THROW(expression, TException) \
199 ::sol3::log::details::UnwrapImpl<decltype((expression)), TException>::impl( \
200 std::forward<decltype((expression))>(expression), \
203 (char const*)(__PRETTY_FUNCTION__), \
205 "[SOL3_UNWRAP_OR_THROW] called unwrap on an invalid `{}`", \
209 #define SOL3_UNWRAP(expression) \
210 SOL3_UNWRAP_OR_THROW(expression, ::sol3::log::ContractViolation)
213 #define SOL3_PANIC(...) \
215 ::sol3::log::ContractViolation, \
217 ::fmt::format(__VA_ARGS__));
222 #define SOL3_EXPECT(condition, ...) \
224 if (!(condition)) { \
226 ::sol3::log::ContractViolation, \
227 "SOL3_EXPECT({}, {})", \
229 ::fmt::format(__VA_ARGS__)); \
233 #define SOL3_IMPL_EXPECT_OP(symbol, name_str, lhs, rhs, ...) \
235 if (!((lhs)symbol(rhs))) { \
237 ::sol3::log::ContractViolation, \
238 "SOL3_EXPECT_{}({} {} {})\n{}\nvs.\n{}\n{}", \
245 ::fmt::format(__VA_ARGS__)); \
252 #define SOL3_EXPECT_EQ(lhs, rhs, ...) \
253 SOL3_IMPL_EXPECT_OP(==, "EQ", lhs, rhs, __VA_ARGS__)
258 #define SOL3_EXPECT_NE(lhs, rhs, ...) \
259 SOL3_IMPL_EXPECT_OP(!=, "NE", lhs, rhs, __VA_ARGS__)
264 #define SOL3_EXPECT_LE(lhs, rhs, ...) \
265 SOL3_IMPL_EXPECT_OP(<=, "LE", lhs, rhs, __VA_ARGS__)
270 #define SOL3_EXPECT_LT(lhs, rhs, ...) \
271 SOL3_IMPL_EXPECT_OP(<, "LT", lhs, rhs, __VA_ARGS__)
276 #define SOL3_EXPECT_GE(lhs, rhs, ...) \
277 SOL3_IMPL_EXPECT_OP(>=, "GE", lhs, rhs, __VA_ARGS__)
282 #define SOL3_EXPECT_GT(lhs, rhs, ...) \
283 SOL3_IMPL_EXPECT_OP(>, "GT", lhs, rhs, __VA_ARGS__)
300 #define SOL3_GET_OR_THROW(associative_container, key, TException, ...) \
301 ::sol3::log::details::checkedGetFromAssociativeContainer< \
302 decltype((associative_container)), \
305 associative_container, \
307 #associative_container, \
312 ::fmt::format(__VA_ARGS__))
324 #define SOL3_GET(associative_container, key, ...) \
326 associative_container, key, ::sol3::log::ContractViolation, __VA_ARGS__)
329 #define SOL3_AT_OR_THROW(contiguous_container, index, TException, ...) \
330 ::sol3::log::details::checkedAtContiguousContainer< \
331 decltype((contiguous_container)), \
333 contiguous_container, \
335 #contiguous_container, \
340 ::fmt::format(__VA_ARGS__))
343 #define SOL3_AT(contiguous_container, index, ...) \
345 contiguous_container, \
347 ::sol3::log::ContractViolation, \
ContractViolation(std::string const &message, char const *file_name, int line_number, char const *function_name, boost::stacktrace::stacktrace stacktrace=boost::stacktrace::stacktrace{})
std::string short_message
Definition: except.h:36
char const * function_name
Definition: except.h:40
boost::stacktrace::stacktrace stacktrace
Definition: except.h:37
ExceptionBase(std::string const &short_message, char const *file_name, int line_number, char const *function_name, boost::stacktrace::stacktrace stacktrace=boost::stacktrace::stacktrace{})
char const * file_name
Definition: except.h:38
int line_number
Definition: except.h:39
InvalidResource(std::string const &message, char const *file_name, int line_number, char const *function_name, boost::stacktrace::stacktrace stacktrace=boost::stacktrace::stacktrace{})
auto checkedGetFromAssociativeContainer(TContainer &container, TKey const &key, char const *container_cstr, char const *key_cstr, char const *file, int line, char const *func, std::string msg) -> decltype(*(container.find(key)))
Definition: except.h:121
auto checkedAtContiguousContainer(TContainer &container, size_t index, char const *container_cstr, char const *index_cstr, char const *file, int line, char const *func, std::string msg) -> decltype(container[index])
Definition: except.h:147
static auto impl(TExpected &&expected, char const *file, int line, char const *func, std::string msg) -> decltype(*std::forward< TExpected >(expected))
Definition: except.h:94
static auto impl(TWrapper &&wrapper, char const *file, int line, char const *func, std::string msg) -> decltype(*std::forward< TWrapper >(wrapper))
Definition: except.h:76