SPH
Outcome.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 
11 
12 struct SuccessTag {};
13 
14 struct FailTag {};
15 
19 template <typename TError>
20 struct OutcomeTraits {
21 
23  INLINE static TError defaultError();
24 
26  INLINE static TError concatenate(const TError& e1, const TError& e2);
27 };
28 
29 template <>
30 struct OutcomeTraits<std::string> {
31  INLINE static std::string defaultError() {
32  return "ERROR";
33  }
34 
35  INLINE static std::string concatenate(const std::string& e1, const std::string& e2) {
36  return e1 + " AND " + e2;
37  }
38 };
39 
43 template <typename TError>
44 class BasicOutcome {
45 private:
47 
48 public:
51 
54  : e(OutcomeTraits<TError>::defaultError()) {}
55 
59  INLINE explicit BasicOutcome(const bool value) {
60  if (!value) {
62  }
63  }
64 
66  template <typename T, typename = std::enable_if_t<std::is_constructible<TError, T>::value>>
67  INLINE explicit BasicOutcome(T&& error)
68  : e(std::forward<T>(error)) {}
69 
71  INLINE bool success() const {
72  return !e;
73  }
74 
76  INLINE explicit operator bool() const {
77  return success();
78  }
79 
81  INLINE bool operator!() const {
82  return !success();
83  }
84 
88  INLINE const TError& error() const {
89  SPH_ASSERT(!success());
90  return e.value();
91  }
92 
96  bool operator==(const BasicOutcome& other) const {
97  return (!e && !other.e) || (e == other.e);
98  }
99 
101  friend std::ostream& operator<<(std::ostream& stream, const BasicOutcome& outcome) {
102  if (outcome) {
103  stream << "success";
104  } else {
105  stream << outcome.error();
106  }
107  return stream;
108  }
109 
113  friend BasicOutcome operator||(const BasicOutcome& o1, const BasicOutcome& o2) {
114  if (!o1 && !o2) {
116  }
117  return SuccessTag{};
118  }
119 
124  friend BasicOutcome operator&&(const BasicOutcome& o1, const BasicOutcome& o2) {
125  if (!o1 && !o2) {
127  } else if (!o1) {
128  return BasicOutcome(o1.error());
129  } else if (!o2) {
130  return BasicOutcome(o2.error());
131  } else {
132  return SuccessTag{};
133  }
134  }
135 };
136 
139 
142 
143 namespace Detail {
144 INLINE void printArgs(std::stringstream&) {}
145 
146 template <typename T0, typename... TArgs>
147 INLINE void printArgs(std::stringstream& ss, T0&& t0, TArgs&&... args) {
148  ss << t0;
149  printArgs(ss, std::forward<TArgs>(args)...);
150 }
151 } // namespace Detail
152 
156 template <typename... TArgs>
157 INLINE Outcome makeFailed(TArgs&&... args) {
158  std::stringstream ss;
159  Detail::printArgs(ss, std::forward<TArgs>(args)...);
160  SPH_ASSERT(!ss.str().empty());
161  return Outcome(ss.str());
162 }
163 
167 template <typename... TArgs>
168 INLINE Outcome makeOutcome(const bool condition, TArgs&&... args) {
169  if (condition) {
170  return SUCCESS;
171  } else {
172  std::stringstream ss;
173  Detail::printArgs(ss, std::forward<TArgs>(args)...);
174  SPH_ASSERT(!ss.str().empty());
175  return Outcome(ss.str());
176  }
177 }
178 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Wrapper of type value of which may or may not be present.
BasicOutcome< std::string > Outcome
Alias for string error message.
Definition: Outcome.h:138
INLINE Outcome makeOutcome(const bool condition, TArgs &&... args)
Constructs outcome object given the condition.
Definition: Outcome.h:168
const SuccessTag SUCCESS
Global constant for successful outcome.
Definition: Outcome.h:141
INLINE Outcome makeFailed(TArgs &&... args)
Constructs failed object with error message.
Definition: Outcome.h:157
Expected-like class that does not contain any value.
Definition: Outcome.h:44
INLINE BasicOutcome(T &&error)
Constructs object given error message.
Definition: Outcome.h:67
friend BasicOutcome operator||(const BasicOutcome &o1, const BasicOutcome &o2)
Logical 'or' operator, returning SUCCESS if either of the values is a SUCCESS.
Definition: Outcome.h:113
INLINE const TError & error() const
Returns the error message.
Definition: Outcome.h:88
friend std::ostream & operator<<(std::ostream &stream, const BasicOutcome &outcome)
Prints "success" or error message into the output stream.
Definition: Outcome.h:101
INLINE BasicOutcome(const bool value)
Constructs object from boolean result.
Definition: Outcome.h:59
bool operator==(const BasicOutcome &other) const
Compares two outcomes.
Definition: Outcome.h:96
INLINE BasicOutcome(SuccessTag)
Constructs object with success (no error)
Definition: Outcome.h:50
INLINE bool success() const
Checks whether the object contains success, i.e. no error is stored.
Definition: Outcome.h:71
friend BasicOutcome operator&&(const BasicOutcome &o1, const BasicOutcome &o2)
Logical 'and' operator, returning SUCCESS if both values are SUCCESS.
Definition: Outcome.h:124
INLINE bool operator!() const
Inversion operator.
Definition: Outcome.h:81
INLINE BasicOutcome(FailTag)
Constructs object with defautl error message.
Definition: Outcome.h:53
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
void emplace(TArgs &&... args)
Constructs the uninitialized object from a list of arguments.
Definition: Optional.h:95
INLINE void printArgs(std::stringstream &)
Definition: Outcome.h:144
Overload of std::swap for Sph::Array.
Definition: Array.h:578
static INLINE std::string defaultError()
Definition: Outcome.h:31
static INLINE std::string concatenate(const std::string &e1, const std::string &e2)
Definition: Outcome.h:35
Utility functions used within BasicOutcome.
Definition: Outcome.h:20
static INLINE TError concatenate(const TError &e1, const TError &e2)
Concatenated two error messages.
static INLINE TError defaultError()
Helper function returning default error message.