DO NOT DEFINE CUSTOM ERROR TYPES. There is one good explanation for that – one can not merge two custom types automatically, however error codes can be merged.
5 #include <outcome/outcome.hpp>
7 namespace my::super:lib {
9 Case1 = 1, // NOTE: MUST NOT start with 0 (it represents success)
11 Case3 = 4, // any codes may be used
12 Case4 // or no codes at all
15 outcome::result<int> calc(int a, int b);
17 // declare required functions in hpp
18 // outside of any namespace
19 OUTCOME_HPP_DECLARE_ERROR(my::super::lib, MyError);
26 // outside of any namespace
27 OUTCOME_CPP_DEFINE_CATEGORY(my::super::lib, MyError, e){
28 using my::super::lib::MyError; // not necessary, just for convenience
30 case MyError::Case1: return "Case1 message";
31 case MyError::Case2: return "Case2 message";
32 case MyError::Case3: return "Case3 message";
33 case MyError::Case4: return "Case4 message";
34 default: return "unknown"; // NOTE: do not forget to handle everything else
38 namespace my::super::lib {
39 outcome::result<int> calc(int a, int b){
40 // then simply return enum in case of error:
41 if(a < 0) return MyError::Case1;
42 if(a > 100) return MyError::Case2;
43 if(b < 0) return MyError::Case3;
44 if(b < 100) return MyError::Case4;
46 return a + b; // simply return value in case of value:
4 #include <outcome/outcome.hpp>
6 namespace my::super:lib {
10 // MyError now is a member of class
11 + enum class MyError {
12 + Case1 = 1, // NOTE: MUST NOT start with 0 (it represents success)
14 + Case3 = 4, // any codes may be used
15 + Case4 // or no codes at all
18 outcome::result<int> calc(int a, int b);
21 // declare required functions in hpp
22 // outside of any namespace
23 +// NOTE: 1 args is only namespace, class prefix should be added to enum
24 -OUTCOME_HPP_DECLARE_ERROR(my::super::lib, MyError);
25 +OUTCOME_HPP_DECLARE_ERROR(my::super::lib, MyLib::MyError);
31 -OUTCOME_CPP_DEFINE_CATEGORY(my::super::lib, MyError, e){
32 +OUTCOME_CPP_DEFINE_CATEGORY(my::super::lib, MyLib::MyError, e){
33 - using my::super::lib::MyError; // not necessary, just for convenience
34 + using my::super::lib::MyLib::MyError; // not necessary, just for convenience
36 case MyError::Case1: return "Case1 message";
37 case MyError::Case2: return "Case2 message";
38 case MyError::Case3: return "Case3 message";
39 case MyError::Case4: return "Case4 message";
40 default: return "unknown"; // NOTE: do not forget to handle everything else
44 namespace my::super::lib {
45 - outcome::result<int> calc(int a, int b)
46 + outcome::result<int> MyLib::calc(int a, int b){
47 // then simply return enum in case of error:
48 if(a < 0) return MyError::Case1;
49 if(a > 100) return MyError::Case2;
50 if(b < 0) return MyError::Case3;
51 if(b > 100) return MyError::Case4;
53 return a + b; // simply return value in case of value
3 outcome::result<int> calc(int a, int b){
4 // then simply return enum in case of error:
5 if(a < 0) return MyError::Case1;
6 if(a > 100) return MyError::Case2;
7 if(b < 0) return MyError::Case3;
8 if(b < 100) return MyError::Case4;
10 return a + b; // simply return value in case of value:
13 outcome::result<int> parent(int a) {
14 // NOTE: returns error if calc returned it, otherwise get unwrapped calc result
15 OUTCOME_TRY(val, calc(a, 1); // use convenient macro
20 auto&& result = calc(a, 2);
23 auto&& v = result.value();
27 auto&& e = result.error(); // get std::error_code
33 // pass result to parent