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
28namespace original {
29
61 template<typename TYPE>
71 union storage {
72 TYPE type_;
73 null null_;
74
78 storage() noexcept;
79
81 storage(const storage& other) noexcept = default;
82
84 storage& operator=(const storage& other) noexcept = default;
85
87 ~storage();
88 };
89
90 bool non_null_type_;
91 storage val_;
92
99 void destroy() noexcept;
100
101 public:
106 explicit alternative();
107
114 template<typename... Args>
115 explicit alternative(Args&&... args);
116
123
131
137 alternative(alternative&& other) noexcept;
138
146
153 void swap(alternative& other) noexcept;
154
160 const TYPE& operator*() const;
161
167 TYPE& operator*();
168
174 const TYPE* operator->() const;
175
181 TYPE* operator->();
182
187 const TYPE* get() const;
188
193 TYPE* get();
194
199 void reset() noexcept;
200
207 template<typename... Args>
208 void emplace(Args&&... args);
209
215 void set(const TYPE& t);
216
237 alternative& operator=(const TYPE& t);
238
243 explicit operator bool() const;
244
249 [[nodiscard]] bool hasValue() const;
250
255 ~alternative();
256 };
257
277 template<>
279 bool has_value_ = false;
280
281 public:
286 explicit alternative();
287
293 explicit alternative(null n);
294
300 explicit alternative(std::in_place_t t);
301
306 void set() noexcept;
307
332
363
368 void reset() noexcept;
369
374 [[nodiscard]] bool hasValue() const;
375
380 explicit operator bool() const;
381
384
387
390
393
400
403 };
404}
405
419 template<typename TYPE>
421}
422template<typename TYPE>
424{
425 new(&this->null_) null;
426}
427
428template<typename TYPE>
430
431template<typename TYPE>
433 if (this->non_null_type_){
434 this->val_.type_.~TYPE();
435 this->non_null_type_ = false;
436 } else {
437 this->val_.null_.~null();
438 this->non_null_type_ = true;
439 }
440}
441
442template<typename TYPE>
444 : non_null_type_(false), val_() {}
445
446template<typename TYPE>
447template<typename... Args>
449 : non_null_type_(true), val_() {
450 new (&this->val_.type_) TYPE{ std::forward<Args>(args)... };
451}
452
453template<typename TYPE>
455 this->non_null_type_ = other.non_null_type_;
456 if (other.non_null_type_) {
457 new (&val_.type_) TYPE{ other.val_.type_ };
458 } else {
459 new (&val_.null_) null;
460 }
461}
462
463template<typename TYPE>
466 if (this == &other)
467 return *this;
468
469 this->destroy();
470 this->non_null_type_ = other.non_null_type_;
471 if (other.non_null_type_) {
472 new (&val_.type_) TYPE{ other.val_.type_ };
473 } else {
474 new (&val_.null_) null;
475 }
476 return *this;
477}
478
479template<typename TYPE>
481 this->non_null_type_ = other.non_null_type_;
482 if (this->non_null_type_){
483 new (&val_.type_) TYPE{ std::move(other.val_.type_) };
484 } else{
485 new (&val_.null_) null;
486 }
487}
488
489template<typename TYPE>
492 if (this == &other)
493 return *this;
494
495 this->destroy();
496 this->non_null_type_ = other.non_null_type_;
497 if (this->non_null_type_){
498 new (&val_.type_) TYPE{ std::move(other.val_.type_) };
499 } else{
500 new (&val_.null_) null;
501 }
502 return *this;
503}
504
505template <typename TYPE>
507{
508 if (this == &other)
509 return;
510
511 std::swap(this->non_null_type_, other.non_null_type_);
512 std::swap(this->val_, other.val_);
513}
514
515template<typename TYPE>
516const TYPE&
518 if (!this->non_null_type_)
519 throw valueError("Dereferencing a original::null value");
520
521 return this->val_.type_;
522}
523
524template<typename TYPE>
525TYPE&
527 if (!this->non_null_type_)
528 throw valueError("Dereferencing a original::null value");
529
530 return this->val_.type_;
531}
532
533template<typename TYPE>
534const TYPE*
536 if (!this->non_null_type_)
537 throw valueError("Accessing member of a original::null value");
538
539 return &this->val_.type_;
540}
541
542template<typename TYPE>
543TYPE*
545 if (!this->non_null_type_)
546 throw valueError("Accessing member of a original::null value");
547
548 return &this->val_.type_;
549}
550
551template<typename TYPE>
553 return this->non_null_type_ ? &this->val_.type_ : nullptr;
554}
555
556template<typename TYPE>
558 return this->non_null_type_ ? &this->val_.type_ : nullptr;
559}
560
561template<typename TYPE>
563 this->destroy();
564}
565
566template<typename TYPE>
567template<typename... Args>
569 this->destroy();
570 this->non_null_type_ = true;
571 new (&val_.type_) TYPE{ std::forward<Args>(args)... };
572}
573
574template<typename TYPE>
576 this->destroy();
577 this->non_null_type_ = true;
578 new (&val_.type_) TYPE{ t };
579}
580
581template <typename TYPE>
584{
585 this->set(t);
586 return *this;
587}
588
589template<typename TYPE>
591 return this->non_null_type_;
592}
593
594template <typename TYPE>
596{
597 return this->operator bool();
598}
599
600template<typename TYPE>
602 this->destroy();
603}
604
606
608
609inline original::alternative<void>::alternative(std::in_place_t) : has_value_(true) {}
610
612{
613 this->has_value_ = true;
614}
615
618{
619 this->set();
620 return *this;
621}
622
625{
626 this->reset();
627 return *this;
628}
629
631{
632 this->has_value_ = false;
633}
634
636{
637 return this->has_value_;
638}
639
641{
642 return this->has_value_;
643}
644
646{
647 this->has_value_ = other.has_value_;
648 other.has_value_ = false;
649}
650
653{
654 if (this == &other)
655 return *this;
656
657 this->has_value_ = other.has_value_;
658 other.has_value_ = false;
659 return *this;
660}
661
663{
664 if (this == &other)
665 return;
666
667 std::swap(this->has_value_, other.has_value_);
668}
669
670template <typename TYPE>
672{
673 lhs.swap(rhs);
674}
675
676#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:62
void set(const TYPE &t)
Sets value by copy.
Definition optional.h:575
alternative()
Constructs an empty alternative.
Definition optional.h:443
void emplace(Args &&... args)
Constructs value in-place.
Definition optional.h:568
bool hasValue() const
Checks if contains a value.
Definition optional.h:595
void reset() noexcept
Resets to empty state.
Definition optional.h:562
alternative & operator=(const alternative &other)
Copy assignment.
Definition optional.h:465
const TYPE * get() const
Gets const pointer to value.
Definition optional.h:552
~alternative()
Destructor.
Definition optional.h:601
const TYPE & operator*() const
Const value access.
Definition optional.h:517
const TYPE * operator->() const
Const member access.
Definition optional.h:535
void swap(alternative &other) noexcept
Swaps contents with another alternative.
Definition optional.h:506
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
A placeholder type representing the absence of a value.
Definition types.h:33
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Abstract base class for unique element containers.
Definition set.h:44
Exception for invalid parameter values.
Definition error.h:219
Custom exception classes and callback validation utilities.
Main namespace for the project Original.
Definition algorithms.h:21
Standard namespace extensions for original::alternative.
Definition allocator.h:351
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635
Core type system foundations and concept definitions.