Hermes
result.h
1 
28 #ifndef HERMES_HERMES_COMMON_RESULT_H
29 #define HERMES_HERMES_COMMON_RESULT_H
30 
31 #include <hermes/common/defs.h>
32 
34 enum class HeResult {
35  SUCCESS = 0,
36  ERROR = 1,
37  BAD_ALLOCATION = 2,
38  OUT_OF_BOUNDS = 3,
39  INVALID_INPUT = 4,
40  BAD_OPERATION = 5,
41  NOT_IMPLEMENTED = 6,
42 };
43 
44 namespace hermes {
45 
46 template<class T>
48  T value{};
49 };
50 
51 // *********************************************************************************************************************
52 // Result
53 // *********************************************************************************************************************
55 template<class T, class E = HeResult>
56 class Result {
57 public:
58  // *******************************************************************************************************************
59  // STATIC FUNCTIONS
60  // *******************************************************************************************************************
66  }
67  // *******************************************************************************************************************
68  // CONSTRUCTORS
69  // *******************************************************************************************************************
72  HERMES_DEVICE_CALLABLE explicit Result(const UnexpectedResultType<E> &err = {}) : ok_(false) {
73  new(reinterpret_cast<E *>(&err_)) E(err.value);
74  }
77  HERMES_DEVICE_CALLABLE explicit Result(const T &v) : ok_(true) {
78  new(reinterpret_cast<T *>(&value_)) T(v);
79  }
82  HERMES_DEVICE_CALLABLE explicit Result(T &&v) : ok_(true) {
83  new(reinterpret_cast<T *>(&value_)) T(std::move(v));
84  }
85  // assignment
89  *this = other;
90  }
93  HERMES_DEVICE_CALLABLE Result(Result &&other) noexcept {
94  *this = std::move(other);
95  }
96  // *******************************************************************************************************************
97  // OPERATORS
98  // *******************************************************************************************************************
101  HERMES_DEVICE_CALLABLE explicit operator bool() const noexcept { return ok_; }
102  // assignment
107  reset();
108  ok_ = other.ok_;
109  if (other.ok_)
110  new(reinterpret_cast<T *>(&value_)) T(other.value());
111  else
112  new(reinterpret_cast<E *>(&err_)) E(other.status());
113  return *this;
114  }
119  reset();
120  ok_ = other.ok_;
121  if (other.ok_)
122  new(reinterpret_cast<T *>(&value_)) T(std::move(other.value()));
123  else
124  new(reinterpret_cast<E *>(&err_)) E(std::move(other.status()));
125  return *this;
126  }
131  reset();
132  ok_ = true;
133  new(reinterpret_cast<T *>(&value_)) T(v);
134  return *this;
135  }
140  reset();
141  ok_ = true;
142  new(reinterpret_cast<T *>(&value_)) T(std::move(v));
143  return *this;
144  }
145  // access
151  HERMES_DEVICE_CALLABLE const T *operator->() const { return &value(); }
157  HERMES_DEVICE_CALLABLE const T &operator*() const { return value(); }
158  // *******************************************************************************************************************
159  // METHODS
160  // *******************************************************************************************************************
161  [[nodiscard]] HERMES_DEVICE_CALLABLE bool good() const { return ok_; }
162  [[nodiscard]] HERMES_DEVICE_CALLABLE E status() const { return err_; }
165  if (good()) {
166  value().~T();
167  ok_ = false;
168  }
169  }
170  // access
174  HERMES_DEVICE_CALLABLE T valueOr(const T &v) const { return good() ? value() : v; }
178  return *reinterpret_cast<T *>(&value_);
179  }
182  HERMES_DEVICE_CALLABLE const T &value() const {
183  return *reinterpret_cast<const T *>(&value_);
184  }
185  // *******************************************************************************************************************
186  // PUBLIC FIELDS
187  // *******************************************************************************************************************
188 private:
189  union {
190  E err_{};
191  typename std::aligned_storage<sizeof(T), alignof(T)>::type value_;
192  };
193  bool ok_{false};
194 };
195 
196 }
197 
198 #endif //HERMES_HERMES_COMMON_RESULT_H
Holds a valid object or an error.
Definition: result.h:56
HERMES_DEVICE_CALLABLE Result & operator=(Result &&other) noexcept
Move assignment.
Definition: result.h:118
HERMES_DEVICE_CALLABLE const T & value() const
Gets value's const reference.
Definition: result.h:182
HERMES_DEVICE_CALLABLE const T & operator*() const
Gets value const reference.
Definition: result.h:157
HERMES_DEVICE_CALLABLE Result(T &&v)
Move value constructor.
Definition: result.h:82
HERMES_DEVICE_CALLABLE Result & operator=(T &&v)
Move value assignment.
Definition: result.h:139
HERMES_DEVICE_CALLABLE Result(Result &&other) noexcept
Move constructor.
Definition: result.h:93
HERMES_DEVICE_CALLABLE Result & operator=(const Result &other)
Copy assignment.
Definition: result.h:106
HERMES_DEVICE_CALLABLE Result(const Result &other)
Copy constructor.
Definition: result.h:88
HERMES_DEVICE_CALLABLE T valueOr(const T &v) const
Gets value copy (if present)
Definition: result.h:174
HERMES_DEVICE_CALLABLE T * operator->()
Gets value pointer.
Definition: result.h:148
static HERMES_DEVICE_CALLABLE Result< T, E > error(E e)
Definition: result.h:64
HERMES_DEVICE_CALLABLE Result(const T &v)
Value constructor.
Definition: result.h:77
HERMES_DEVICE_CALLABLE T & operator*()
Gets value reference.
Definition: result.h:154
HERMES_DEVICE_CALLABLE Result & operator=(const T &v)
Value assignment.
Definition: result.h:130
HERMES_DEVICE_CALLABLE const T * operator->() const
Gets const value pointer.
Definition: result.h:151
HERMES_DEVICE_CALLABLE void reset()
Destroys stored value (if present)
Definition: result.h:164
HERMES_DEVICE_CALLABLE T & value()
Gets value's reference.
Definition: result.h:177
HERMES_DEVICE_CALLABLE Result(const UnexpectedResultType< E > &err={})
Definition: result.h:72
Data type definitions.
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
Definition: result.h:47