wren
Vulkan-based game engine
Loading...
Searching...
No Matches
errors.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <fmt/core.h>
4#include <fmt/format.h>
5#include <fmt/ostream.h>
6
7#include <boost/preprocessor.hpp>
8#include <optional>
9#include <system_error>
10#include <tl/expected.hpp>
11
12#include "enums.hpp"
13#include "macros.hpp"
14
15namespace wren {
16
17class Err {
18 public:
19 template <typename T>
20 Err(T error) : error_code_(make_error_code(error)) {}
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) {}
24
25 [[nodiscard]] auto error() const { return error_code_; }
26
27 [[nodiscard]] auto message() const { return error_code_.message(); }
28
29 [[nodiscard]] auto extra_msg() const { return extra_message_; }
30
31 private:
32 std::error_code error_code_;
33 std::optional<std::string> extra_message_;
34};
35
36// struct error_code : public std::error_code {
37// error_code(int32_t ec, std::error_category const& cat)
38// : ::error_code(ec, cat) {}
39
40// error_code(std::error_code ec) : std::error_code(ec) {}
41
42// friend auto operator<<(std::ostream& os, error_code const& ec)
43// -> std::ostream& {
44// return os << ec.category().name() << " : " << ec.message();
45// }
46// };
47
48template <typename T>
49using expected = tl::expected<T, Err>;
50
51} // namespace wren
52
53template <>
54struct fmt::formatter<wren::Err> : fmt::formatter<std::string> {
55 auto format(wren::Err, fmt::format_context& ctx) const
56 -> decltype(ctx.out());
57};
58
61#define DEFINE_ERROR_IMPL(CAT_NAME, ERROR_ENUM) \
62 class ERROR_ENUM##_category_t : public std::error_category { \
63 public: \
64 [[nodiscard]] auto name() const noexcept -> const char* final { \
65 return CAT_NAME; \
66 } \
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)}; \
72 } \
73 }; \
74 inline auto ERROR_ENUM##_category() \
75 -> const ERROR_ENUM##_category_t& { \
76 static const ERROR_ENUM##_category_t kC; \
77 return kC; \
78 } \
79 inline auto make_error_code(ERROR_ENUM ec) -> std::error_code { \
80 return {static_cast<int32_t>(ec), ERROR_ENUM##_category()}; \
81 }
82
90#define DEFINE_ERROR(cat_name, name, ...) \
91 BOOST_DEFINE_ENUM_CLASS(name, __VA_ARGS__); \
92 DEFINE_ERROR_IMPL(cat_name, name)
93
94#define RESULT_UNIQUE_NAME() BOOST_PP_CAT(__result_tmp, __COUNTER__)
95
96#define TRY_RESULT_IMPL(unique, expr) \
97 auto unique = (expr); \
98 if (!(unique).has_value()) \
99 return tl::make_unexpected(unique.error());
100
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();
105
106#define TRY_RESULT(...) \
107 BOOST_PP_OVERLOAD(TRY_RESULT_, __VA_ARGS__) \
108 (RESULT_UNIQUE_NAME(), __VA_ARGS__)
109
110#define TRY_RESULT_VOID_IMPL(unique, expr) \
111 auto unique = (expr); \
112 if (!(unique).has_value()) return;
113
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__)
122
132// NOLINTNEXTLINE
133#define ERR_VAL_OR(out, err, on_err) \
134 const auto LINEIZE(res, __LINE__) = err; \
135 if (!LINEIZE(res, __LINE__).has_value()) { \
136 on_err \
137 } \
138 out = LINEIZE(res, __LINE__).value();
139
146// NOLINTNEXTLINE
147#define ERR_VOID_OR(err, on_err) \
148 const auto LINEIZE(res, __LINE__) = err; \
149 if (!LINEIZE(res, __LINE__).has_value()) { \
150 on_err \
151 }
Definition errors.hpp:17
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
Definition editor.hpp:14
tl::expected< T, Err > expected
Definition errors.hpp:49