Stax
Programming language
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <boost/describe.hpp>
4#include <boost/describe/enum_to_string.hpp>
5#include <boost/outcome.hpp>
6#include <boost/preprocessor/cat.hpp>
7#include <boost/preprocessor/stringize.hpp>
8#include <filesystem> // IWYU pragma: export
9#include <optional>
10#include <string>
11#include <system_error>
12
13#include "utils.hpp" // IWYU pragma: export
14
15namespace stax::result {
16
17template <typename T>
18struct is_error_enum : std::false_type {};
19
20template <typename T>
21concept IsErrorCode = requires { make_error_code(T{}); };
22
23class Err {
24 public:
25 template <IsErrorCode T>
26 Err(const T& ec, const std::optional<std::string>& msg = {})
27 : ec_(make_error_code(ec)), extra_msg_(msg) {}
28
29 Err(const std::error_code& ec, const std::optional<std::string>& msg = {})
30 : ec_(ec), extra_msg_(msg) {}
31
32 template <IsErrorCode T>
33 auto operator==(const T& ec) const {
34 return ec_ == make_error_code(ec);
35 }
36
37 template <IsErrorCode T>
38 auto operator!=(const T& ec) const {
39 return !(ec_ == ec);
40 }
41
42 auto Code() {
43 return ec_;
44 }
45
46 auto message() {
47 return extra_msg_;
48 }
49
50 private:
51 std::error_code ec_;
52 std::optional<std::string> extra_msg_;
53
54 BOOST_DESCRIBE_CLASS(Err, (), (), (), (ec_, extra_msg_));
55};
56
57inline auto Ok() {
58 return boost::outcome_v2::success();
59}
60
61} // namespace stax::result
62
63namespace stax {
64
65template <typename T>
66using result_t =
67 boost::outcome_v2::result<T, result::Err,
68 boost::outcome_v2::policy::terminate>;
69
70}
71
72#define DEFINE_ERROR_IMPL(module_name, ERROR_ENUM) \
73 class ERROR_ENUM##_category_t : public std::error_category { \
74 public: \
75 const char* name() const noexcept override { \
76 return (module_name BOOST_PP_STRINGIZE(_##ERROR_ENUM)); \
77 } \
78 std::string message(int32_t e) const override { \
79 const auto ec = static_cast<ERROR_ENUM>(e); \
80 return boost::describe::enum_to_string(ec, ""); \
81 } \
82 }; \
83 inline auto ERROR_ENUM##_category()->const ERROR_ENUM##_category_t& { \
84 static const ERROR_ENUM##_category_t e_cat{}; \
85 return e_cat; \
86 } \
87 inline auto make_error_code(ERROR_ENUM ec) -> std::error_code { \
88 return {static_cast<int32_t>(ec), ERROR_ENUM##_category()}; \
89 }
90
91#define DEFINE_ERROR(module_name, name, ...) \
92 BOOST_DEFINE_ENUM_CLASS(name, __VA_ARGS__) \
93 DEFINE_ERROR_IMPL(module_name, name)
94
95#define RESULT_UNIQUE_NAME() BOOST_PP_CAT(__result_, __COUNTER__)
96
97#define TRY_RESULT(...) BOOST_OUTCOME_TRY(__VA_ARGS__)
98
99#define TRY_RESULT_IMPL(unique_name, expr, alt) \
100 auto unique_name = expr; \
101 alt
102
103#define TRY_RESULT_OR(expr, alt) \
104 TRY_RESULT_IMPL(RESULT_UNIQUE_NAME(), expr, alt)
105
106// inline const std::string mod = GET_MODULE_NAME()
Definition result.hpp:23
auto operator==(const T &ec) const
Definition result.hpp:33
Err(const T &ec, const std::optional< std::string > &msg={})
Definition result.hpp:26
Err(const std::error_code &ec, const std::optional< std::string > &msg={})
Definition result.hpp:29
auto Code()
Definition result.hpp:42
auto operator!=(const T &ec) const
Definition result.hpp:38
auto message()
Definition result.hpp:46
Definition result.hpp:21
Definition result.hpp:15
auto Ok()
Definition result.hpp:57
Definition lexer.cpp:8
boost::outcome_v2::result< T, result::Err, boost::outcome_v2::policy::terminate > result_t
Definition result.hpp:66
Definition result.hpp:18