ORIGINAL
Loading...
Searching...
No Matches
optional.h
Go to the documentation of this file.
1#ifndef ORIGINAL_OPTIONAL_H
2#define ORIGINAL_OPTIONAL_H
3#include <utility>
4#include "types.h"
5#include "error.h"
6
25namespace original {
26
44 template<typename TYPE>
52 union storage {
53 TYPE type_;
54 none none_;
55
59 storage() noexcept;
60
62 storage(const storage& other) noexcept = default;
63
65 storage& operator=(const storage& other) noexcept = default;
66
68 ~storage();
69 };
70
71 bool non_none_type_;
72 storage val_;
73
78 void destroy() noexcept;
79
80 public:
85 explicit alternative();
86
93 template<typename... Args>
94 explicit alternative(Args&&... args);
95
101 alternative(const alternative& other);
102
109 alternative& operator=(const alternative& other);
110
116 alternative(alternative&& other) noexcept;
117
124 alternative& operator=(alternative&& other) noexcept;
125
131 const TYPE& operator*() const;
132
138 TYPE& operator*();
139
145 const TYPE* operator->() const;
146
152 TYPE* operator->();
153
158 const TYPE* get() const;
159
164 TYPE* get();
165
170 void reset() noexcept;
171
178 template<typename... Args>
179 void emplace(Args&&... args);
180
186 void set(const TYPE& t);
187
192 explicit operator bool() const;
193
198 [[nodiscard]] bool hasValue() const;
199
204 ~alternative();
205 };
206
214 template<>
215 class alternative<void> {
216 bool has_value_ = false;
217
218 public:
223 explicit alternative();
224
230 explicit alternative(none n);
231
237 explicit alternative(std::in_place_t t);
238
243 void set();
244
249 void reset() noexcept;
250
255 [[nodiscard]] bool hasValue() const;
256
261 explicit operator bool() const;
262
264 alternative(const alternative& other) = default;
265
267 alternative& operator=(const alternative& other) = default;
268
270 alternative(alternative&& other) noexcept = default;
271
273 alternative& operator=(alternative&& other) noexcept = default;
274
276 ~alternative() = default;
277 };
278}
279
280template<typename TYPE>
281original::alternative<TYPE>::storage::storage() noexcept
282{
283 new(&this->none_) none{};
284}
285
286template<typename TYPE>
288
289template<typename TYPE>
291 if (this->non_none_type_){
292 this->val_.type_.~TYPE();
293 this->non_none_type_ = false;
294 } else {
295 this->val_.none_.~none();
296 this->non_none_type_ = true;
297 }
298}
299
300template<typename TYPE>
302 : non_none_type_(false), val_() {}
303
304template<typename TYPE>
305template<typename... Args>
307 : non_none_type_(true), val_() {
308 new (&this->val_.type_) TYPE{ std::forward<Args>(args)... };
309}
310
311template<typename TYPE>
313 this->non_none_type_ = other.non_none_type_;
314 if (other.non_none_type_) {
315 new (&val_.type_) TYPE{ other.val_.type_ };
316 } else {
317 new (&val_.none_) none{};
318 }
319}
320
321template<typename TYPE>
324 if (this == &other)
325 return *this;
326
327 this->destroy();
328 this->non_none_type_ = other.non_none_type_;
329 if (other.non_none_type_) {
330 new (&val_.type_) TYPE{ other.val_.type_ };
331 } else {
332 new (&val_.none_) none{};
333 }
334 return *this;
335}
336
337template<typename TYPE>
339 this->non_none_type_ = other.non_none_type_;
340 if (this->non_none_type_){
341 new (&val_.type_) TYPE{ std::move(other.val_.type_) };
342 } else{
343 new (&val_.none_) none{};
344 }
345}
346
347template<typename TYPE>
350 if (this == &other)
351 return *this;
352
353 this->destroy();
354 this->non_none_type_ = other.non_none_type_;
355 if (this->non_none_type_){
356 new (&val_.type_) TYPE{ std::move(other.val_.type_) };
357 } else{
358 new (&val_.none_) none{};
359 }
360 return *this;
361}
362
363template<typename TYPE>
364const TYPE&
366 if (!this->non_none_type_)
367 throw valueError("Dereferencing a original::none value");
368
369 return this->val_.type_;
370}
371
372template<typename TYPE>
373TYPE&
375 if (!this->non_none_type_)
376 throw valueError("Dereferencing a original::none value");
377
378 return this->val_.type_;
379}
380
381template<typename TYPE>
382const TYPE*
384 if (!this->non_none_type_)
385 throw valueError("Accessing member of a original::none value");
386
387 return &this->val_.type_;
388}
389
390template<typename TYPE>
391TYPE*
393 if (!this->non_none_type_)
394 throw valueError("Accessing member of a original::none value");
395
396 return &this->val_.type_;
397}
398
399template<typename TYPE>
401 return this->non_none_type_ ? &this->val_.type_ : nullptr;
402}
403
404template<typename TYPE>
406 return this->non_none_type_ ? &this->val_.type_ : nullptr;
407}
408
409template<typename TYPE>
411 this->destroy();
412}
413
414template<typename TYPE>
415template<typename... Args>
417 this->destroy();
418 this->non_none_type_ = true;
419 new (&val_.type_) TYPE{ std::forward<Args>(args)... };
420}
421
422template<typename TYPE>
424 this->destroy();
425 this->non_none_type_ = true;
426 new (&val_.type_) TYPE{ t };
427}
428
429template<typename TYPE>
431 return this->non_none_type_;
432}
433
434template <typename TYPE>
436{
437 return this->operator bool();
438}
439
440template<typename TYPE>
442 this->destroy();
443}
444
446
448
449inline original::alternative<void>::alternative(std::in_place_t) : has_value_(true) {}
450
452{
453 this->has_value_ = true;
454}
455
457{
458 this->has_value_ = false;
459}
460
462{
463 return this->has_value_;
464}
465
467{
468 return this->has_value_;
469}
470
471#endif //ORIGINAL_OPTIONAL_H
alternative()
Constructs an empty alternative<void>
A type-safe container that may or may not contain a value.
Definition optional.h:45
void set(const TYPE &t)
Sets value by copy.
Definition optional.h:423
alternative()
Constructs an empty alternative.
Definition optional.h:301
void emplace(Args &&... args)
Constructs value in-place.
Definition optional.h:416
bool hasValue() const
Checks if contains a value.
Definition optional.h:435
void reset() noexcept
Resets to empty state.
Definition optional.h:410
alternative & operator=(const alternative &other)
Copy assignment.
Definition optional.h:323
const TYPE * get() const
Gets const pointer to value.
Definition optional.h:400
~alternative()
Destructor.
Definition optional.h:441
const TYPE & operator*() const
Const value access.
Definition optional.h:365
const TYPE * operator->() const
Const member access.
Definition optional.h:383
A placeholder type representing the absence of a value.
Definition types.h:32
constexpr ~none()=default
Default destructor (constexpr)
Exception for invalid parameter values.
Definition error.h:150
Custom exception classes and callback validation utilities.
Main namespace for the project Original.
Definition algorithms.h:21
Core type system foundations and concept definitions.