@@ -74,48 +74,72 @@ namespace Rust {
74
74
template <typename T> class Optional
75
75
{
76
76
private:
77
- struct Empty
77
+ struct tag_some
78
78
{
79
79
};
80
-
81
- enum Kind
80
+ struct tag_none
82
81
{
83
- Some,
84
- None
85
- } kind;
82
+ };
86
83
87
- union Content
84
+ bool field_is_some;
85
+
86
+ union
88
87
{
89
- Empty empty;
90
88
T value;
89
+ };
91
90
92
- Content () = default ;
93
- } content;
91
+ Optional (tag_some, const T &value) : field_is_some ( true ), value (value) {}
92
+ Optional (tag_some, T &&value) : field_is_some ( true ), value (value) {}
94
93
95
- Optional<T> (Kind kind, Content content ) : kind (kind), content (content ) {}
94
+ Optional (tag_none ) : field_is_some ( false ) {}
96
95
97
96
public:
98
- Optional (const Optional &other) = default ;
99
- Optional &operator = (const Optional &other) = default ;
100
- Optional (Optional &&other) = default ;
97
+ Optional (const Optional &other)
98
+ {
99
+ if ((field_is_some = other.field_is_some ))
100
+ new (&value) T (other.value );
101
+ }
101
102
102
- static Optional<T> some (T value )
103
+ Optional (Optional &&other )
103
104
{
104
- Content content;
105
- content.value = value;
105
+ if ((field_is_some = other.field_is_some ))
106
+ new (&value) T (other.value );
107
+ }
106
108
107
- return Optional (Kind::Some, content);
109
+ Optional &operator = (const Optional &other)
110
+ {
111
+ if (is_some ())
112
+ value.~T ();
113
+ if ((field_is_some = other.field_is_some ))
114
+ new (&value) T (other.value );
115
+ return *this ;
108
116
}
109
117
110
- static Optional<T> none ( )
118
+ Optional & operator = (Optional &&other )
111
119
{
112
- Content content;
113
- content.empty = Empty ();
120
+ if (is_some ())
121
+ value.~T ();
122
+ if ((field_is_some = other.field_is_some ))
123
+ new (&value) T (other.value );
124
+ return *this ;
125
+ }
114
126
115
- return Optional (Kind::None, content);
127
+ ~Optional ()
128
+ {
129
+ if (is_some ())
130
+ value.~T ();
116
131
}
117
132
118
- bool is_some () const { return kind == Kind::Some; }
133
+ static Optional some (const T &value)
134
+ {
135
+ return Optional (tag_some (), value);
136
+ }
137
+
138
+ static Optional some (T &&value) { return Optional (tag_some (), value); }
139
+
140
+ static Optional none () { return Optional (tag_none ()); }
141
+
142
+ bool is_some () const { return field_is_some; }
119
143
bool is_none () const { return !is_some (); }
120
144
121
145
/* *
@@ -135,24 +159,24 @@ template <typename T> class Optional
135
159
{
136
160
rust_assert (is_some ());
137
161
138
- return content. value ;
162
+ return value;
139
163
}
140
164
141
165
T &get ()
142
166
{
143
167
rust_assert (is_some ());
144
168
145
- return content. value ;
169
+ return value;
146
170
}
147
171
148
172
T take ()
149
173
{
150
174
rust_assert (is_some ());
151
175
152
- auto to_return = std::move (content.value );
176
+ T to_return = std::move (value);
177
+ value.~T ();
153
178
154
- content.empty = Empty ();
155
- kind = Kind::None;
179
+ field_is_some = false ;
156
180
157
181
return to_return;
158
182
}
0 commit comments