Skip to content

Commit 0b217b9

Browse files
[Interop][SwiftToCxx] Initial implementation
1 parent 9cebd69 commit 0b217b9

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

lib/PrintAsClang/_SwiftCxxInteroperability.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,89 @@ template <class T> inline void *_Nonnull getOpaquePointer(T &value) {
195195

196196
} // namespace _impl
197197

198+
/// The Expected class has either an error or an value.
199+
template<class T>
200+
class Expected {
201+
public:
202+
203+
/// Default
204+
constexpr Expected() { has_val = false; }
205+
constexpr Expected(T buf) : buffer(buf) { has_val = true; }
206+
constexpr Expected(swift::Error * _Nonnull error_val) : err(error_val) { has_val = false; }
207+
208+
/// Copy
209+
constexpr Expected(Expected const& other) noexcept {
210+
if (other.has_value()) {
211+
buffer = other.buffer;
212+
has_val = true;
213+
}
214+
}
215+
/// Move
216+
constexpr Expected(Expected&& other) noexcept {
217+
if (other.has_value()) {
218+
buffer = other.buffer;
219+
has_val = true;
220+
}
221+
}
222+
223+
~Expected() noexcept { }
224+
225+
/// assignment
226+
constexpr auto operator=(Expected&& other) noexcept { auto temp = buffer; buffer = other.buffer; other.buffer = temp; }
227+
constexpr auto operator=(Expected&) noexcept = delete;
228+
229+
/// For accessing T's members
230+
// precondition: has_value() == true
231+
constexpr T const* _Nonnull operator->() const noexcept { return &buffer; }
232+
233+
// precondition: has_value() == true
234+
constexpr T* _Nonnull operator->() noexcept { return &buffer; }
235+
236+
/// Getting reference to T
237+
// precondition: has_value() == true
238+
constexpr T const& operator*() const& noexcept { return buffer; }
239+
240+
// precondition: has_value() == true
241+
constexpr T& operator*() & noexcept { return buffer; }
242+
243+
constexpr explicit operator bool() const noexcept {
244+
return has_value();
245+
}
246+
247+
// Get value, if not exists abort
248+
// FIXME: throw exception instead of abort?
249+
constexpr T const& value() const& {
250+
if (!has_value())
251+
abort();
252+
return *reinterpret_cast<const T *>(buffer);
253+
}
254+
255+
constexpr T& value() & {
256+
if (!has_value())
257+
abort();
258+
return *reinterpret_cast<T *>(buffer);
259+
}
260+
261+
// Get error
262+
constexpr swift::Error const& error() const& {
263+
if (has_value())
264+
abort();
265+
return err;
266+
}
267+
constexpr swift::Error& error() & {
268+
if (has_value())
269+
abort();
270+
return err;
271+
}
272+
273+
constexpr bool has_value() const noexcept { return has_val; }
274+
275+
private:
276+
T buffer;
277+
swift::Error err;
278+
bool has_val;
279+
};
280+
198281
#pragma clang diagnostic pop
199282

200283
} // namespace swift

0 commit comments

Comments
 (0)