tcalc 0.2.0
 
Loading...
Searching...
No Matches
error.hpp
Go to the documentation of this file.
1
12#pragma once
13
14#include <cerrno>
15#include <cstdint>
16#include <cstdio>
17#include <cstring>
18#include <exception>
19#include <string>
20#include <unordered_map>
21
22#ifdef TCALC_USE_TL_EXPECTED
23#include <tl/expected.hpp>
24#define _TCALC_EXPECTED_NS tl
25#else
26#include <expected>
27#define _TCALC_EXPECTED_NS std
28#endif
29
30#include "tcalc/common.hpp"
31
32#define ret_err(expr) \
33 if (auto res = (expr); !res.has_value()) { \
34 return _TCALC_EXPECTED_NS::unexpected(res.error()); \
35 }
36
37#define unwrap_err(expr) \
38 ({ \
39 auto _ret = (expr); \
40 if (!_ret.has_value()) { \
41 return _TCALC_EXPECTED_NS::unexpected(_ret.error()); \
42 } \
43 _ret.value(); \
44 })
45
46#define log_err(expr) \
47 { \
48 auto _ret = (expr); \
49 if (!_ret.has_value()) { \
50 _ret.error().log(); \
51 } \
52 }
53
54#define log_err_exit(expr) \
55 { \
56 auto _ret = (expr); \
57 if (!_ret.has_value()) { \
58 _ret.error().log(); \
59 std::exit(EXIT_FAILURE); \
60 } \
61 }
62
63namespace tcalc::error {
64
79
80inline const std::unordered_map<Code, std::string> CODE_NAMES = {
81 { Code::SYNTAX_ERROR, "SYNAX_ERROR" },
82 { Code::UNDEFINED_VAR, "UNDEFINED_VAR" },
83 { Code::UNDEFINED_FUNC, "UNDEFINED_FUNC" },
84 { Code::MISMATCHED_ARGS, "MISMATCHED_ARGS" },
85 { Code::ZERO_DIVISION, "ZERO_DIVISION" },
86 { Code::RECURSION_LIMIT, "RECURSION_LIMIT" },
87 { Code::FILE_NOT_FOUND, "FILE_NOT_FOUND" },
88};
94class TCALC_PUBLIC Error : public std::exception
95{
96public:
97 constexpr static std::size_t MAX_MSG_LEN = 256;
99private:
100 Code _code;
101 std::string _msg;
102
103public:
110 Error(Code code, std::string msg) noexcept
111 : _code{ code }
112 , _msg{ std::move(msg) }
113 {
114 }
115
121 [[nodiscard]] TCALC_INLINE auto code() const noexcept { return _code; }
122
128 [[nodiscard]] TCALC_INLINE const auto& msg() const noexcept { return _msg; }
129
134 void log() const noexcept;
135
141 [[nodiscard]] const char* what() const noexcept override
142 {
143 return _msg.c_str();
144 }
145};
146
152template<typename T>
153using Result = _TCALC_EXPECTED_NS::expected<T, Error>;
154
162TCALC_INLINE auto
163err(Code code, const std::string& message) noexcept
164{
165 return _TCALC_EXPECTED_NS::unexpected(Error(code, message));
166}
167
174TCALC_INLINE auto
175raw_err(Code code) noexcept
176{
177 auto errno_copy = errno;
178 return Error(code,
179 errno_copy == 0 ? "Unknown error" : std::strerror(errno_copy));
180}
181
188TCALC_INLINE auto
189err(Code code) noexcept
190{
191 return _TCALC_EXPECTED_NS::unexpected(raw_err(code));
192}
193
204TCALC_PRINTF_FORMAT(2, 3)
205_TCALC_EXPECTED_NS::unexpected<Error>
206err(Code code, const char* fmt, ...) noexcept;
207
216template<typename T, typename... Args>
217TCALC_INLINE auto
218ok(Args&&... args) noexcept
219{
220 return _TCALC_EXPECTED_NS::expected<T, Error>(T(std::forward<Args>(args)...));
221}
222
228template<>
229TCALC_INLINE auto
230ok<void>() noexcept
231{
232 return _TCALC_EXPECTED_NS::expected<void, Error>();
233}
234
235}
Error class.
Definition error.hpp:95
Error(Code code, std::string msg) noexcept
Construct a new Error object (should be noexcept in semantic).
Definition error.hpp:110
TCALC_INLINE const auto & msg() const noexcept
Get error message.
Definition error.hpp:128
TCALC_INLINE auto code() const noexcept
Get error code.
Definition error.hpp:121
tcalc common header.
TCALC_INLINE auto err(Code code, const std::string &message) noexcept
Create an error.
Definition error.hpp:163
_TCALC_EXPECTED_NS::expected< T, Error > Result
Result type.
Definition error.hpp:153
Code
Error code.
Definition error.hpp:70
TCALC_INLINE auto raw_err(Code code) noexcept
Create a raw error with errno.
Definition error.hpp:175
const std::unordered_map< Code, std::string > CODE_NAMES
Definition error.hpp:80