Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef CPP_RESULT | ||
2 | #define CPP_RESULT | ||
3 | |||
4 | #include <source_location> | ||
5 | #include <sstream> | ||
6 | #include <string> | ||
7 | #include <variant> | ||
8 | |||
9 | namespace cpp | ||
10 | { | ||
11 | namespace result | ||
12 | { | ||
13 | class error | ||
14 | { | ||
15 | public: | ||
16 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | error(const char* err) : m_msg(err) {} |
17 | 7 | error(const std::string& err) : m_msg(err) {} | |
18 | |||
19 | 6 | const std::string& msg() const | |
20 | { | ||
21 | 6 | return m_msg; | |
22 | } | ||
23 | |||
24 | private: | ||
25 | const std::string m_msg; | ||
26 | }; | ||
27 | |||
28 | static const std::string msg_invalid_call{"Invalid call of err_msg()."}; | ||
29 | |||
30 | template <typename T> class result | ||
31 | { | ||
32 | public: | ||
33 | static_assert(!std::is_same<T, cpp::result::error>::value, | ||
34 | "T cannot be of type cpp::result::error"); | ||
35 | |||
36 | 5 | result(const T& data) : m_value(data) {} | |
37 | |||
38 | 12 | result(const error& err) : m_value(err) {} | |
39 | |||
40 | 55 | bool error() const noexcept | |
41 | { | ||
42 | 55 | return std::holds_alternative<cpp::result::error>(m_value); | |
43 | } | ||
44 | |||
45 | 27 | bool valid() const noexcept | |
46 | { | ||
47 | 27 | return !error(); | |
48 | } | ||
49 | |||
50 | 1 | const T& value() const | |
51 | { | ||
52 | static_assert(!std::is_same<T, std::monostate>::value, | ||
53 | "value() cannot be called on result_void"); | ||
54 | |||
55 | 1 | return std::get<T>(m_value); | |
56 | } | ||
57 | |||
58 | 12 | const std::string& err_msg() const | |
59 | { | ||
60 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
|
12 | if (!error()) |
61 | 4 | return msg_invalid_call; | |
62 | |||
63 | 8 | return std::get<cpp::result::error>(m_value).msg(); | |
64 | } | ||
65 | |||
66 | private: | ||
67 | const std::variant<T, cpp::result::error> m_value; | ||
68 | }; | ||
69 | |||
70 | using result_void = result<std::monostate>; | ||
71 | |||
72 | static const result_void SUCCESS{std::monostate{}}; | ||
73 | |||
74 | 4 | cpp::result::error report_error( | |
75 | const char* msg, | ||
76 |
2/30✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
|
4 | const std::source_location& location = std::source_location::current()) |
77 | { | ||
78 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | std::ostringstream error_msg; |
79 | error_msg << msg << " [file: " << location.file_name() | ||
80 | << ", function: " << location.function_name() | ||
81 |
8/16✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
|
4 | << ", line: " << location.line() << "]"; |
82 | |||
83 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
12 | return error_msg.str(); |
84 | 4 | } | |
85 | |||
86 | } // namespace result | ||
87 | } // namespace cpp | ||
88 | |||
89 | #endif | ||
90 |