xtd 0.2.0
Loading...
Searching...
No Matches
optional.hpp
Go to the documentation of this file.
1
3#pragma once
5#define __XTD_STD_INTERNAL__
7#undef __XTD_STD_INTERNAL__
8
9#if defined(__xtd__cpp_lib_optional)
10#include <optional>
11#else
12#include <stdexcept>
13#include <utility>
14
15namespace std {
16 /*
17 class bad_optional_access : public std::exception {
18 public:
19 const char* what() const noexcept override {return "bad optional access";}
20 };
21 */
22
23 template <typename value_t>
24 class optional {
25 private:
26 alignas(value_t) unsigned char data_[sizeof(value_t)];
27 bool has_value_;
28
29 public:
30 optional() : has_value_(false) {}
31
32 optional(const value_t& value) : has_value_(true) {
33 new (data_) value_t(value);
34 }
35
36 optional(value_t&& value) : has_value_(true) {
37 new (data_) value_t(std::move(value));
38 }
39
40 optional(const optional& other) : has_value_(other.has_value_) {
41 if (other.has_value_) {
42 new (data_) value_t(*other);
43 }
44 }
45
46 optional(optional&& other) : has_value_(other.has_value_) {
47 if (other.has_value_) {
48 new (data_) value_t(std::move(*other));
49 }
50 other.reset();
51 }
52
53 optional& operator=(const value_t& value) {
54 if (has_value_) {
55 *reinterpret_cast<value_t*>(data_) = value;
56 } else {
57 new (data_) value_t(value);
58 has_value_ = true;
59 }
60 return *this;
61 }
62
63 optional& operator=(value_t&& value) {
64 if (has_value_) {
65 *reinterpret_cast<value_t*>(data_) = std::move(value);
66 } else {
67 new (data_) value_t(std::move(value));
68 has_value_ = true;
69 }
70 return *this;
71 }
72
73 optional& operator=(const optional& other) {
74 if (this == &other) {
75 return *this;
76 }
77
78 if (other.has_value_) {
79 if (has_value()) {
80 *reinterpret_cast<value_t*>(data_) = *other;
81 } else {
82 new (data_) value_t(*other);
83 has_value_ = true;
84 }
85 } else {
86 reset();
87 }
88 return *this;
89 }
90
91 optional& operator=(optional&& other) {
92 if (this == &other) {
93 return *this;
94 }
95
96 if (other.has_value_) {
97 if (has_value()) {
98 *reinterpret_cast<value_t*>(data_) = std::move(*other);
99 } else {
100 new (data_) value_t(std::move(*other));
101 has_value_ = true;
102 }
103 } else {
104 reset();
105 }
106 other.reset();
107 return *this;
108 }
109
110 ~optional() {
111 reset();
112 }
113
114 bool has_value() const {
115 return has_value_;
116 }
117
118 const value_t& value() const {
119 return operator*();
120 }
121
122 const value_t& value_or(const value_t& other) const {
123 return has_value() ? operator*() : other;
124 }
125
126 void reset() {
127 if (!has_value()) return;
128 reinterpret_cast<value_t*>(data_)->~value_t();
129 has_value_ = false;
130 }
131
132 const value_t* operator->() const {
133 if (!has_value()) {
134 throw std::runtime_error("optional does not contain a value.");
135 }
136 return reinterpret_cast<const value_t*>(data_);
137 }
138
139 value_t* operator->() {
140 if (!has_value_) {
141 throw std::runtime_error("optional does not contain a value.");
142 }
143 return reinterpret_cast<value_t*>(data_);
144 }
145
146 const value_t& operator*() const {
147 return *operator->();
148 }
149
150 value_t& operator*() {
151 return *operator->();
152 }
153
154 explicit operator bool() const {
155 return has_value_;
156 }
157 };
158}
159#endif
161
165#pragma once
166#include "optional.hpp"
167
169namespace xtd {
180 template<typename type_t>
181 using optional = std::optional<type_t>;
182}
Contains __xtd_std_version definitions.
std::optional< type_t > optional
Represents the null_opt alias on std::nullopt_t.
Definition optional.hpp:181
@ other
The operating system is other.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10
Contains xtd::optional type.