5#include <fmt/ostream.h>
7#include <boost/preprocessor.hpp>
10#include <tl/expected.hpp>
21 Err(std::error_code
const& ec) : error_code_(ec) {}
22 Err(int32_t ec, std::error_category
const& e_cat)
23 : error_code_(ec, e_cat) {}
25 [[nodiscard]]
auto error()
const {
return error_code_; }
27 [[nodiscard]]
auto message()
const {
return error_code_.message(); }
29 [[nodiscard]]
auto extra_msg()
const {
return extra_message_; }
32 std::error_code error_code_;
33 std::optional<std::string> extra_message_;
54struct fmt::formatter<
wren::Err> : fmt::formatter<std::string> {
55 auto format(
wren::Err, fmt::format_context& ctx)
const
56 ->
decltype(ctx.out());
61#define DEFINE_ERROR_IMPL(CAT_NAME, ERROR_ENUM) \
62 class ERROR_ENUM##_category_t : public std::error_category { \
64 [[nodiscard]] auto name() const noexcept -> const char* final { \
67 [[nodiscard]] auto message(int32_t c) const \
68 -> std::string final { \
69 auto e = static_cast<ERROR_ENUM>(c); \
70 using namespace boost::describe; \
71 return std::string{enum_to_string(e)}; \
74 inline auto ERROR_ENUM##_category() \
75 -> const ERROR_ENUM##_category_t& { \
76 static const ERROR_ENUM##_category_t kC; \
79 inline auto make_error_code(ERROR_ENUM ec) -> std::error_code { \
80 return {static_cast<int32_t>(ec), ERROR_ENUM##_category()}; \
90#define DEFINE_ERROR(cat_name, name, ...) \
91 BOOST_DEFINE_ENUM_CLASS(name, __VA_ARGS__); \
92 DEFINE_ERROR_IMPL(cat_name, name)
94#define RESULT_UNIQUE_NAME() BOOST_PP_CAT(__result_tmp, __COUNTER__)
96#define TRY_RESULT_IMPL(unique, expr) \
97 auto unique = (expr); \
98 if (!(unique).has_value()) \
99 return tl::make_unexpected(unique.error());
101#define TRY_RESULT_1(unique, expr) TRY_RESULT_IMPL(unique, expr)
102#define TRY_RESULT_2(unique, out, expr) \
103 TRY_RESULT_IMPL(unique, expr) \
104 out = (unique).value();
106#define TRY_RESULT(...) \
107 BOOST_PP_OVERLOAD(TRY_RESULT_, __VA_ARGS__) \
108 (RESULT_UNIQUE_NAME(), __VA_ARGS__)
110#define TRY_RESULT_VOID_IMPL(unique, expr) \
111 auto unique = (expr); \
112 if (!(unique).has_value()) return;
114#define TRY_RESULT_VOID_1(unique, expr) \
115 TRY_RESULT_VOID_IMPL(unique, expr)
116#define TRY_RESULT_VOID_2(unique, out, expr) \
117 TRY_RESULT_VOID_IMPL(unique, expr) \
118 out = (unique).value();
119#define TRY_RESULT_VOID(...) \
120 BOOST_PP_OVERLOAD(TRY_RESULT_VOID_, __VA_ARGS__) \
121 (RESULT_UNIQUE_NAME(), __VA_ARGS__)
133#define ERR_VAL_OR(out, err, on_err) \
134 const auto LINEIZE(res, __LINE__) = err; \
135 if (!LINEIZE(res, __LINE__).has_value()) { \
138 out = LINEIZE(res, __LINE__).value();
147#define ERR_VOID_OR(err, on_err) \
148 const auto LINEIZE(res, __LINE__) = err; \
149 if (!LINEIZE(res, __LINE__).has_value()) { \
Err(int32_t ec, std::error_category const &e_cat)
Definition errors.hpp:22
Err(std::error_code const &ec)
Definition errors.hpp:21
auto extra_msg() const
Definition errors.hpp:29
auto error() const
Definition errors.hpp:25
auto message() const
Definition errors.hpp:27
Err(T error)
Definition errors.hpp:20
tl::expected< T, Err > expected
Definition errors.hpp:49