Lodestar
An integrated real-time control package in C++
StatusOr.hpp
1 //
2 // Created by Hamza El-Kebir on 6/17/21.
3 //
4 
5 #ifndef LODESTAR_STATUSOR_HPP
6 #define LODESTAR_STATUSOR_HPP
7 
8 #include "Status.hpp"
9 #include <type_traits>
10 
11 namespace ls {
12  namespace core {
13  template<typename TType>
14  class StatusOr {
15  // Allow access to private/protected variables/methods in all other StatusOr instances.
16  template<typename> friend
17  class StatusOr;
18 
19  public:
20  using type = TType;
21 
22  StatusOr();
23 
24  StatusOr(const Status &status);
25 
26  StatusOr(const TType &value);
27 
28  StatusOr(const StatusOr &other);
29 
30  template<typename TTypeOther>
31  StatusOr(const StatusOr<TTypeOther> &other,
32  typename std::enable_if<std::is_convertible<TTypeOther, TType>::value>::type * = nullptr);
33 
34  template<typename TTypeOther>
35  StatusOr(const StatusOr<TTypeOther> &other,
36  typename std::enable_if<!std::is_convertible<TTypeOther, TType>::value>::type * = nullptr);
37 
38  StatusOr &operator=(const StatusOr &other);
39 
40  template<typename TTypeOther>
41  typename std::enable_if<std::is_convertible<TTypeOther, TType>::value, StatusOr &>::type
42  operator=(const StatusOr<TTypeOther> &other)
43  {
44  status_ = other.status_;
45  if (status_.ok())
46  value_ = other.value_;
47 
48  return *this;
49  }
50 
51  template<typename TTypeOther>
52  typename std::enable_if<!std::is_convertible<TTypeOther, TType>::value, StatusOr &>::type
53  operator=(const StatusOr<TTypeOther> &other)
54  {
55  static_assert(std::is_convertible<TTypeOther, TType>::value,
56  "StatusOr value must be convertible.");
57 
58  return *this;
59  }
60 
61  const Status &status() const;
62 
63  bool ok() const;
64 
65  inline explicit operator bool() const;
66 
67  const TType &value() const;
68 
69  protected:
70  Status status_;
71  TType value_;
72  };
73 
74  template<typename TType>
75  inline StatusOr<TType>::StatusOr() : status_(util::UnknownError())
76  {}
77 
78  template<typename TType>
79  inline StatusOr<TType>::StatusOr(const Status &status)
80  {
81  if (status.ok())
82  status_ = util::InternalError(); // OkStatus is not a valid argument.
83  else
84  status_ = status;
85  }
86 
87  template<typename TType>
88  inline StatusOr<TType>::StatusOr(const TType &value)
89  {
90  if (!std::is_pointer<decltype(&value)>::value)
91  status_ = util::InternalError(); // nullptr is not a valid argument.
92  else {
93  status_ = util::OkStatus();
94  value_ = value;
95  }
96  }
97 
98  template<typename TType>
99  inline StatusOr<TType>::StatusOr(const StatusOr &other) : status_(
100  other.status_), value_(other.value_)
101  {}
102 
103  template<typename TType>
104  template<typename TTypeOther>
105  inline StatusOr<TType>::StatusOr(const StatusOr<TTypeOther> &other,
106  typename std::enable_if<std::is_convertible<TTypeOther, TType>::value>::type *)
107  : status_(other.status_),
108  value_(other.status_.ok() ? other.value_
109  : TType{})
110  {}
111 
112  template<typename TType>
113  template<typename TTypeOther>
114  inline StatusOr<TType>::StatusOr(const StatusOr<TTypeOther> &other,
115  typename std::enable_if<!std::is_convertible<TTypeOther, TType>::value>::type *)
116  {
117  static_assert(std::is_convertible<TTypeOther, TType>::value,
118  "StatusOr value must be convertible.");
119  }
120 
121  template<typename TType>
122  inline StatusOr<TType> &
123  StatusOr<TType>::operator=(const StatusOr &other)
124  {
125  status_ = other.status_;
126  value_ = other.value_;
127 
128  return *this;
129  }
130 
131  template<typename TType>
132  inline const Status &StatusOr<TType>::status() const
133  { return status_; }
134 
135  template<typename TType>
136  inline bool StatusOr<TType>::ok() const
137  { return status_.ok(); }
138 
139  template<typename TType>
140  StatusOr<TType>::operator bool() const
141  { return ok(); }
142 
143  template<typename TType>
144  const TType &StatusOr<TType>::value() const
145  {
146  if (!status_.ok()) {
147  // TODO: Implement StatusOrHelper::Crash(status_) by adding logging mechanism.
148  }
149 
150  return value_;
151  }
152  }
153 }
154 
155 #endif //LODESTAR_STATUSOR_HPP
ls::core::StatusOr
Definition: StatusOr.hpp:14
ls
Main Lodestar code.
Definition: BilinearTransformation.hpp:12
ls::core::Status
Definition: Status.hpp:31