Flex  0.17.9
result.h
Go to the documentation of this file.
1 
16 #ifndef UTILS_RESULT_H_
17 #define UTILS_RESULT_H_
18 
19 #include <filesystem>
20 #include <iomanip>
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 
25 #include "flex/utils/error_pb/interactive.pb.h"
26 
27 #include "glog/logging.h"
28 
29 namespace gs {
30 
31 using StatusCode = gs::flex::interactive::Code;
32 
33 class Status {
34  public:
35  Status() noexcept;
36  Status(StatusCode error_code) noexcept;
37  Status(StatusCode error_code, std::string&& error_msg) noexcept;
38  Status(StatusCode error_code, const std::string& error_msg) noexcept;
39  bool ok() const;
40  std::string error_message() const;
41  StatusCode error_code() const;
42 
43  static Status OK();
44 
45  std::string ToString() const;
46 
47  private:
49  std::string error_msg_;
50 };
51 
52 // Define a class with name Result<T>, which is a template class
53 // Stores the result of a function that may fail.
54 // If the function succeeds, the result contains the value returned by the
55 // function. If the function fails, the result contains the error message. The
56 // result is always valid and can be queried for success or failure. If the
57 // result is successful, the value can be obtained by calling the value()
58 // method. If the result fails, the error message can be obtained by calling the
59 // error() method. The result can be converted to bool, and the result is true
60 // if the result is successful. The result can be converted to bool, and the
61 // result is false if the result fails.
62 template <typename T>
63 class Result {
64  public:
65  using ValueType = T;
69  : status_(StatusCode::OK), value_(std::move(value)) {}
71  : status_(status), value_(std::move(value)) {}
72 
74 
76  : status_(status), value_(value) {}
77 
78  Result(StatusCode code, const std::string& error_msg, const ValueType& value)
79  : status_(code, error_msg), value_(value) {}
80 
81  Result(StatusCode code, std::string&& error_msg, const ValueType& value)
82  : status_(code, std::move(error_msg)), value_(value) {}
83 
84  bool ok() const noexcept { return status_.ok(); }
85 
86  const Status& status() const noexcept { return status_; }
87  ValueType& value() noexcept { return value_; }
88 
89  // return rvalue
90  ValueType&& move_value() noexcept { return std::move(value_); }
91 
92  private:
95 };
96 
97 template <typename T>
98 struct is_gs_result_type : std::false_type {};
99 
100 template <typename T>
101 struct is_gs_result_type<Result<T>> : std::true_type {};
102 
103 template <typename T>
104 struct is_gs_status_type : std::false_type {};
105 
106 template <>
107 struct is_gs_status_type<Status> : std::true_type {};
108 
109 // define a macro, which checks the return status of a function, if ok, continue
110 // to execute, otherwise, return the status.
111 // the macro accept the calling code of a function, and the function name.
112 #define RETURN_IF_NOT_OK(expr) \
113  do { \
114  auto status = (expr); \
115  if (!status.ok()) { \
116  return status; \
117  } \
118  } while (0)
119 
120 // a Macro automatically assign the return value of a function, which returns
121 // result to a variable, and check the status of the result, if ok, continue to
122 // execute, otherwise, return the status. the macro accept the calling code of a
123 // function, the function name, and the variable name.
124 // reference:
125 // https://github.com/boostorg/leaf/blob/develop/include/boost/leaf/error.hpp
126 #define ASSIGN_AND_RETURN_IF_RESULT_NOT_OK(var, expr) \
127  { \
128  auto&& FLEX_TMP_VAR = expr; \
129  static_assert( \
130  ::gs::is_gs_result_type< \
131  typename std::decay<decltype(FLEX_TMP_VAR)>::type>::value, \
132  "The expression must return a Result type"); \
133  if (!FLEX_TMP_VAR.ok()) { \
134  return FLEX_TMP_VAR; \
135  } \
136  var = std::forward<decltype(FLEX_TMP_VAR)>(FLEX_TMP_VAR).move_value(); \
137  }
138 
139 #define ASSIGN_AND_RETURN_IF_STATUS_NOT_OK(var, expr) \
140  { \
141  auto&& FLEX_TMP_VAR = expr; \
142  static_assert( \
143  ::gs::is_gs_status_type< \
144  typename std::decay<decltype(FLEX_TMP_VAR)>::type>::value, \
145  "The expression must return a Status type"); \
146  if (!FLEX_TMP_VAR.ok()) { \
147  return FLEX_TMP_VAR; \
148  } \
149  var = std::forward<decltype(FLEX_TMP_VAR)>(FLEX_TMP_VAR).move_value(); \
150  }
151 
152 // A Marco automatically use a auto variable to store the return value of a
153 // function, which returns result, and check the status of the result, if ok,
154 // continue to execute, otherwise, return the status. the macro accept the
155 // calling code of a function, the function name, and the variable name.
156 #define FLEX_AUTO(var, expr) ASSIGN_AND_RETURN_IF_NOT_OK(auto var, expr)
157 
158 // Return boost::leaf::error object with error code and error message,
159 
160 #define RETURN_FLEX_LEAF_ERROR(code, msg) \
161  return ::boost::leaf::new_error( \
162  gs::Status(::gs::flex::interactive::Code::code, msg))
163 
164 } // namespace gs
165 
166 namespace std {
167 inline std::string to_string(const gs::flex::interactive::Code& status) {
168  // format the code into 0x-xxxx, where multiple zeros are prepend to the code
169  std::stringstream ss;
170  ss << "05-" << std::setw(4) << std::setfill('0')
171  << static_cast<int32_t>(status);
172  return ss.str();
173 }
174 } // namespace std
175 
176 #endif // UTILS_RESULT_H_
Definition: result.h:63
T ValueType
Definition: result.h:65
Result(const Status &status, const ValueType &value)
Definition: result.h:75
Status status_
Definition: result.h:93
Result(const Status &status, ValueType &&value)
Definition: result.h:70
Result(StatusCode code, std::string &&error_msg, const ValueType &value)
Definition: result.h:81
Result(StatusCode code, const std::string &error_msg, const ValueType &value)
Definition: result.h:78
ValueType value_
Definition: result.h:94
Result()
Definition: result.h:66
bool ok() const noexcept
Definition: result.h:84
ValueType & value() noexcept
Definition: result.h:87
Result(ValueType &&value)
Definition: result.h:68
Result(const Status &status)
Definition: result.h:73
const Status & status() const noexcept
Definition: result.h:86
ValueType && move_value() noexcept
Definition: result.h:90
Result(const ValueType &value)
Definition: result.h:67
Definition: result.h:33
bool ok() const
Definition: result.cc:33
StatusCode error_code_
Definition: result.h:48
Status() noexcept
Definition: result.cc:19
std::string error_message() const
Definition: result.cc:29
std::string error_msg_
Definition: result.h:49
std::string ToString() const
Definition: result.cc:37
StatusCode error_code() const
Definition: result.cc:31
static Status OK()
Definition: result.cc:35
Definition: adj_list.h:23
gs::flex::interactive::Code StatusCode
Definition: result.h:31
Definition: loading_config.h:232
std::string to_string(const gs::flex::interactive::Code &status)
Definition: result.h:167
Definition: result.h:98
Definition: result.h:104