Apache GraphAr C++ Library
The C++ Library for Apache GraphAr
status.h
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #pragma once
21 
22 #include <sstream>
23 #include <string>
24 #include <utility>
25 
26 #include "graphar/macros.h"
27 
28 #define GAR_RETURN_IF_(condition, status, _) \
29  do { \
30  if (GAR_PREDICT_FALSE(condition)) { \
31  return (status); \
32  } \
33  } while (0)
34 
36 #define GAR_RETURN_NOT_OK(status) \
37  do { \
38  ::graphar::Status __s = ::graphar::internal::GenericToStatus(status); \
39  GAR_RETURN_IF_(!__s.ok(), __s, GAR_STRINGIFY(status)); \
40  } while (false)
41 
43 #define RETURN_NOT_ARROW_OK(status) \
44  do { \
45  if (GAR_PREDICT_FALSE(!status.ok())) { \
46  return ::graphar::Status::ArrowError(status.ToString()); \
47  } \
48  } while (false)
49 
50 #define GAR_RAISE_ERROR_IF_(condition, status, _) \
51  do { \
52  if (GAR_PREDICT_FALSE(condition)) { \
53  throw std::runtime_error(status.message()); \
54  } \
55  } while (0)
56 
58 #define GAR_RAISE_ERROR_NOT_OK(status) \
59  do { \
60  ::graphar::Status __s = ::graphar::internal::GenericToStatus(status); \
61  GAR_RAISE_ERROR_IF_(!__s.ok(), __s, GAR_STRINGIFY(status)); \
62  } while (false)
63 
64 namespace graphar::util {
65 template <typename Head>
66 void StringBuilderRecursive(std::ostringstream& stream, Head&& head) {
67  stream << head;
68 }
69 
70 template <typename Head, typename... Tail>
71 void StringBuilderRecursive(std::ostringstream& stream, Head&& head,
72  Tail&&... tail) {
73  StringBuilderRecursive(stream, std::forward<Head>(head));
74  StringBuilderRecursive(stream, std::forward<Tail>(tail)...);
75 }
76 
77 template <typename... Args>
78 std::string StringBuilder(Args&&... args) {
79  std::ostringstream ss;
80  StringBuilderRecursive(ss, std::forward<Args>(args)...);
81  return ss.str();
82 }
83 } // namespace graphar::util
84 
85 namespace graphar {
89 enum class StatusCode : unsigned char {
90  // success status
91  kOK = 0,
92  // error status for failed key lookups
93  kKeyError,
94  // error status for type errors
95  kTypeError,
96  // error status for invalid data
97  kInvalid,
98  // error status when an index is out of bounds
99  kIndexError,
100  // error status for out-of-memory conditions
101  kOutOfMemory,
102  // error status when some IO-related operation failed
103  kIOError,
104  // error status when some yaml parse related operation failed
105  kYamlError,
106  // error status when some arrow-related operation failed
107  kArrowError,
108 
109  // error status for unknown errors
110  kUnknownError,
111 };
112 
123 class Status {
124  public:
126  Status() noexcept : state_(nullptr) {}
128  ~Status() noexcept {
129  if (state_ != nullptr) {
130  deleteState();
131  }
132  }
138  Status(StatusCode code, const std::string& msg) {
139  state_ = new State;
140  state_->code = code;
141  state_->msg = msg;
142  }
144  inline Status(const Status& s)
145  : state_((s.state_ == nullptr) ? nullptr : new State(*s.state_)) {}
147  inline Status(Status&& s) noexcept : state_(s.state_) { s.state_ = nullptr; }
149  inline Status& operator=(Status&& s) noexcept {
150  delete state_;
151  state_ = s.state_;
152  s.state_ = nullptr;
153  return *this;
154  }
155 
157  inline static Status OK() { return Status(); }
158 
159  template <typename... Args>
160  static Status FromArgs(StatusCode code, Args... args) {
161  return Status(code, util::StringBuilder(std::forward<Args>(args)...));
162  }
163 
165  template <typename... Args>
166  static Status IOError(Args&&... args) {
167  return Status::FromArgs(StatusCode::kIOError, std::forward<Args>(args)...);
168  }
169 
171  template <typename... Args>
172  static Status KeyError(Args&&... args) {
173  return Status::FromArgs(StatusCode::kKeyError, std::forward<Args>(args)...);
174  }
175 
177  template <typename... Args>
178  static Status TypeError(Args&&... args) {
179  return Status::FromArgs(StatusCode::kTypeError,
180  std::forward<Args>(args)...);
181  }
182 
187  template <typename... Args>
188  static Status Invalid(Args&&... args) {
189  return Status::FromArgs(StatusCode::kInvalid, std::forward<Args>(args)...);
190  }
191 
196  template <typename... Args>
197  static Status IndexError(Args&&... args) {
198  return Status::FromArgs(StatusCode::kIndexError,
199  std::forward<Args>(args)...);
200  }
201 
203  template <typename... Args>
204  static Status YamlError(Args&&... args) {
205  return Status::FromArgs(StatusCode::kYamlError,
206  std::forward<Args>(args)...);
207  }
208 
210  template <typename... Args>
211  static Status ArrowError(Args&&... args) {
212  return Status::FromArgs(StatusCode::kArrowError,
213  std::forward<Args>(args)...);
214  }
215 
217  template <typename... Args>
218  static Status UnknownError(Args&&... args) {
219  return Status::FromArgs(StatusCode::kUnknownError,
220  std::forward<Args>(args)...);
221  }
222 
224  constexpr bool ok() const { return (state_ == nullptr); }
225 
227  constexpr bool IsKeyError() const { return code() == StatusCode::kKeyError; }
229  constexpr bool IsTypeError() const {
230  return code() == StatusCode::kTypeError;
231  }
233  constexpr bool IsInvalid() const { return code() == StatusCode::kInvalid; }
235  constexpr bool IsIndexError() const {
236  return code() == StatusCode::kIndexError;
237  }
239  constexpr bool IsYamlError() const {
240  return code() == StatusCode::kYamlError;
241  }
243  constexpr bool IsArrowError() const {
244  return code() == StatusCode::kArrowError;
245  }
246 
248  constexpr StatusCode code() const {
249  return ok() ? StatusCode::kOK : state_->code;
250  }
251 
253  const std::string& message() const {
254  static const std::string no_message = "";
255  return ok() ? no_message : state_->msg;
256  }
257 
258  private:
259  void deleteState() {
260  delete state_;
261  state_ = nullptr;
262  }
263 
264  struct State {
265  StatusCode code;
266  std::string msg;
267  };
268  State* state_;
269 };
270 
271 } // namespace graphar
272 
273 namespace graphar::internal {
274 
275 // Extract Status from Status or Result<T>
276 // Useful for the status check macros such as RETURN_NOT_OK.
277 inline const Status& GenericToStatus(const Status& st) { return st; }
278 inline Status GenericToStatus(Status&& st) { return std::move(st); }
279 
280 } // namespace graphar::internal
Status outcome object (success or error)
Definition: status.h:123
Status(StatusCode code, const std::string &msg)
Constructs a status with the specified error code and message.
Definition: status.h:138
Status() noexcept
Definition: status.h:126
const std::string & message() const
Definition: status.h:253
~Status() noexcept
Definition: status.h:128
static Status IndexError(Args &&... args)
Definition: status.h:197
Status & operator=(Status &&s) noexcept
Definition: status.h:149
static Status TypeError(Args &&... args)
Definition: status.h:178
static Status YamlError(Args &&... args)
Definition: status.h:204
constexpr bool ok() const
Definition: status.h:224
static Status UnknownError(Args &&... args)
Definition: status.h:218
static Status KeyError(Args &&... args)
Definition: status.h:172
static Status ArrowError(Args &&... args)
Definition: status.h:211
constexpr bool IsTypeError() const
Definition: status.h:229
constexpr bool IsKeyError() const
Definition: status.h:227
constexpr bool IsArrowError() const
Definition: status.h:243
constexpr bool IsInvalid() const
Definition: status.h:233
static Status Invalid(Args &&... args)
Definition: status.h:188
constexpr bool IsYamlError() const
Definition: status.h:239
constexpr bool IsIndexError() const
Definition: status.h:235
Status(const Status &s)
Definition: status.h:144
constexpr StatusCode code() const
Definition: status.h:248
static Status OK()
Definition: status.h:157
Status(Status &&s) noexcept
Definition: status.h:147
static Status IOError(Args &&... args)
Definition: status.h:166