Molassembler  1.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Optional.h
Go to the documentation of this file.
1 
8 #ifndef INLCUDE_MOLASSEMBLER_TEMPLE_CONSTEXPR_OPTIONAL_H
9 #define INLCUDE_MOLASSEMBLER_TEMPLE_CONSTEXPR_OPTIONAL_H
10 
12 
13 #include <utility>
14 
15 namespace Scine {
16 namespace Molassembler {
17 namespace Temple {
18 
32 template<typename T>
33 class Optional {
34 public:
37 
41  constexpr Optional() {
42  static_assert(
43  std::is_same<T, std::decay_t<T>>::value,
44  "T must not be a reference or const-qualified type"
45  );
46  }
47 
49  constexpr explicit Optional(T value) : value_(std::move(value)), hasValue_(true) {
50  static_assert(
51  std::is_same<T, std::decay_t<T>>::value,
52  "T must not be a reference or const-qualified type"
53  );
54  }
56 
59 
63  PURITY_WEAK constexpr bool hasValue() const {
64  return hasValue_;
65  }
66 
72  PURITY_WEAK constexpr T value() const {
73  return value_;
74  }
75 
82  template<class UnaryFunction>
83  constexpr auto map(UnaryFunction&& function) const {
84  // Function has signature T -> U
85  using U = decltype(function(value_));
86 
87  if(hasValue_) {
88  return Optional<U> {
89  function(value_)
90  };
91  }
92 
93  return Optional<U> {};
94  }
95 
102  template<class UnaryFunction>
103  constexpr auto flatMap(UnaryFunction&& function) const {
104  // Function has signature T -> Optional<U>
105  using OptionalU = decltype(function(value_));
106 
107  if(hasValue_) {
108  return OptionalU {function(value_)};
109  }
110 
111  return OptionalU {};
112  }
113 
118  PURITY_WEAK constexpr T valueOr(const T& alternative) const {
119  if(hasValue_) {
120  return value_;
121  }
122 
123  return alternative;
124  }
126 
130  constexpr Optional& operator = (T assignment) {
131  value_ = assignment;
132  hasValue_ = true;
133 
134  return *this;
135  }
136 
138  PURITY_WEAK constexpr operator bool () const {
139  return hasValue_;
140  }
141 
143  PURITY_WEAK constexpr bool operator == (const Optional& other) const {
144  if(!hasValue_ && !other.hasValue_) {
145  return true;
146  }
147 
148  if(hasValue_ && other.hasValue_) {
149  return value_ == other.value_;
150  }
151 
152  return false;
153  }
154 
156  PURITY_WEAK constexpr bool operator != (const Optional& other) const {
157  return !(*this == other);
158  }
159 
161  PURITY_WEAK constexpr bool operator < (const Optional& other) const {
162  // If neither has a value, they are equal
163  if(!hasValue_ && !other.hasValue_) {
164  return false;
165  }
166 
167  // If we do not have a value, but the other does, we are smaller
168  if(!hasValue_ && other.hasValue_) {
169  return true;
170  }
171 
172  // If we have a value, but the other doesn't, we are bigger
173  if(hasValue_ && !other.hasValue_) {
174  return false;
175  }
176 
177  // Remaining case: both have values
178  return (
179  value_ < other.value_
180  );
181  }
182 
184  PURITY_WEAK constexpr bool operator > (const Optional& other) const {
185  return (other < *this);
186  }
188 
189 private:
190  T value_ = T {};
191  bool hasValue_ = false;
192 };
193 
194 template<typename T>
195 class Optional<T&> {
196 public:
199 
203  constexpr Optional() : ref_(dummy_) {}
204 
206  constexpr explicit Optional(T& value) : ref_(value), hasValue_(true) {}
208 
211 
215  PURITY_WEAK constexpr bool hasValue() const {
216  return hasValue_;
217  }
218 
224  PURITY_WEAK constexpr T& value() const {
225  return ref_;
226  }
227 
234  template<class UnaryFunction>
235  constexpr auto map(UnaryFunction&& function) const {
236  // Function has signature T -> U
237  using U = decltype(function(ref_));
238 
239  if(hasValue_) {
240  return Optional<U> {
241  function(ref_)
242  };
243  }
244 
245  return Optional<U> {};
246  }
247 
254  template<class UnaryFunction>
255  constexpr auto flatMap(UnaryFunction&& function) const {
256  // Function has signature T -> Optional<U>
257  using OptionalU = decltype(function(ref_));
258 
259  if(hasValue_) {
260  return OptionalU {function(ref_)};
261  }
262 
263  return OptionalU {};
264  }
265 
270  PURITY_WEAK constexpr T valueOr(const T& alternative) const {
271  if(hasValue_) {
272  return ref_;
273  }
274 
275  return alternative;
276  }
278 
282  PURITY_WEAK constexpr operator bool () const {
283  return hasValue_;
284  }
285 
287  PURITY_WEAK constexpr bool operator == (const Optional& other) const {
288  if(!hasValue_ && !other.hasValue_) {
289  return true;
290  }
291 
292  if(hasValue_ && other.hasValue_) {
293  return ref_ == other.ref_;
294  }
295 
296  return false;
297  }
298 
300  PURITY_WEAK constexpr bool operator != (const Optional& other) const {
301  return !(*this == other);
302  }
303 
305  PURITY_WEAK constexpr bool operator < (const Optional& other) const {
306  // If neither has a value, they are equal
307  if(!hasValue_ && !other.hasValue_) {
308  return false;
309  }
310 
311  // If we do not have a value, but the other does, we are smaller
312  if(!hasValue_ && other.hasValue_) {
313  return true;
314  }
315 
316  // If we have a value, but the other doesn't, we are bigger
317  if(hasValue_ && !other.hasValue_) {
318  return false;
319  }
320 
321  // Remaining case: both have values
322  return (
323  ref_ < other.ref_
324  );
325  }
326 
328  PURITY_WEAK constexpr bool operator > (const Optional& other) const {
329  return (other < *this);
330  }
332 
333 private:
334  T dummy_ = T{};
335  T& ref_;
336  bool hasValue_ = false;
337 };
338 
339 } // namespace Temple
340 } // namespace Molassembler
341 } // namespace Scine
342 
343 #endif
PURITY_WEAK constexpr bool operator>(const Optional &other) const
Lexicographical-like comparison.
Definition: Optional.h:184
PURITY_WEAK constexpr bool hasValue() const
Returns whether the optional contains a value.
Definition: Optional.h:215
#define PURITY_WEAK
Definition: Preprocessor.h:36
PURITY_WEAK constexpr bool operator==(const Optional &other) const
Compares on basis of contained value. Nones do compare equal.
Definition: Optional.h:143
An Option monadic type.
Definition: Optional.h:33
constexpr Optional(T value)
Value constructor.
Definition: Optional.h:49
constexpr Optional(T &value)
Value constructor.
Definition: Optional.h:206
constexpr auto flatMap(UnaryFunction &&function) const
Monadic bind with function of signature T -&gt; Optional&lt;U&gt;
Definition: Optional.h:255
PURITY_WEAK constexpr bool hasValue() const
Returns whether the optional contains a value.
Definition: Optional.h:63
constexpr Optional()
Default constructor.
Definition: Optional.h:41
constexpr auto flatMap(UnaryFunction &&function) const
Monadic bind with function of signature T -&gt; Optional&lt;U&gt;
Definition: Optional.h:103
PURITY_WEAK constexpr bool operator<(const Optional &other) const
Lexicographical-like comparison.
Definition: Optional.h:161
PURITY_WEAK constexpr bool operator!=(const Optional &other) const
Compares on basis of contained value. Nones do compare equal.
Definition: Optional.h:156
Defines a set of useful preprocessor macros.
PURITY_WEAK constexpr T & value() const
Returns the contained value unchecked.
Definition: Optional.h:224
PURITY_WEAK constexpr T value() const
Returns the contained value unchecked.
Definition: Optional.h:72
PURITY_WEAK constexpr T valueOr(const T &alternative) const
Returns a value if initialized, and another if not.
Definition: Optional.h:118
constexpr auto map(UnaryFunction &&function) const
Monadic bind with function of signature T -&gt; U.
Definition: Optional.h:235
constexpr auto map(UnaryFunction &&function) const
Monadic bind with function of signature T -&gt; U.
Definition: Optional.h:83
PURITY_WEAK constexpr T valueOr(const T &alternative) const
Returns a value if initialized, and another if not.
Definition: Optional.h:270
constexpr Optional & operator=(T assignment)
Assignment from T.
Definition: Optional.h:130
constexpr Optional()
Default constructor.
Definition: Optional.h:203