summaryrefslogtreecommitdiff
path: root/kernel/lib/libcxx/include/__expected/expected.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lib/libcxx/include/__expected/expected.h')
-rw-r--r--kernel/lib/libcxx/include/__expected/expected.h403
1 files changed, 403 insertions, 0 deletions
diff --git a/kernel/lib/libcxx/include/__expected/expected.h b/kernel/lib/libcxx/include/__expected/expected.h
new file mode 100644
index 0000000..2266cd2
--- /dev/null
+++ b/kernel/lib/libcxx/include/__expected/expected.h
@@ -0,0 +1,403 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the BastionOS freestanding C++ standard library.
+//
+// std::expected (C++23) — no-exceptions version (traps on bad access).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBBASTION_EXPECTED_EXPECTED_H
+#define _LIBBASTION_EXPECTED_EXPECTED_H
+
+#include <__config>
+#include <__type_traits/construction_traits.h>
+#include <__type_traits/type_modifications.h>
+#include <__type_traits/type_relationships.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <__utility/in_place.h>
+#include <new>
+
+_LIBBASTION_BEGIN_NAMESPACE_STD
+
+// ── unexpect tag ────────────────────────────────────────────────────────────
+
+struct unexpect_t { explicit unexpect_t() = default; };
+inline constexpr unexpect_t unexpect{};
+
+// ── unexpected ────────────────────────────────���──────────────────────────���──
+
+template<class _Err>
+class unexpected {
+ static_assert(!__is_void(_Err), "unexpected<void> is ill-formed");
+public:
+ constexpr unexpected(const unexpected&) = default;
+ constexpr unexpected(unexpected&&) = default;
+
+ template<class _Er = _Err>
+ requires (!__is_same(__decay(_Er), unexpected)) && (!__is_same(__decay(_Er), in_place_t)) &&
+ is_constructible_v<_Err, _Er>
+ constexpr explicit unexpected(_Er&& __e) : __val_(std::forward<_Er>(__e)) {}
+
+ template<class... _Args>
+ requires is_constructible_v<_Err, _Args...>
+ constexpr explicit unexpected(in_place_t, _Args&&... __args) : __val_(std::forward<_Args>(__args)...) {}
+
+ _LIBBASTION_NODISCARD constexpr _Err& error() & noexcept { return __val_; }
+ _LIBBASTION_NODISCARD constexpr const _Err& error() const& noexcept { return __val_; }
+ _LIBBASTION_NODISCARD constexpr _Err&& error() && noexcept { return std::move(__val_); }
+ _LIBBASTION_NODISCARD constexpr const _Err&& error() const&& noexcept { return std::move(__val_); }
+
+ template<class _Er2>
+ _LIBBASTION_NODISCARD friend constexpr bool operator==(const unexpected& __x, const unexpected<_Er2>& __y) {
+ return __x.error() == __y.error();
+ }
+
+ constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) {
+ using std::swap;
+ swap(__val_, __other.__val_);
+ }
+
+private:
+ _Err __val_;
+};
+
+template<class _Err>
+unexpected(_Err) -> unexpected<_Err>;
+
+// ── expected<T, E> ───────────────────────────��──────────────────────────────
+
+template<class _Tp, class _Err>
+class expected {
+ static_assert(!__is_void(_Err), "expected<T, void> is ill-formed; use expected<void, E> for void value");
+ static_assert(!__is_reference(_Tp), "expected<T&, E> is ill-formed");
+ static_assert(!__is_reference(_Err), "expected<T, E&> is ill-formed");
+
+public:
+ using value_type = _Tp;
+ using error_type = _Err;
+ using unexpected_type = unexpected<_Err>;
+
+ // ── Constructors ──────────────────────────��─────────────────────────
+
+ constexpr expected()
+ noexcept(is_nothrow_default_constructible_v<_Tp>)
+ requires is_default_constructible_v<_Tp>
+ : __has_val_(true)
+ { ::new (static_cast<void*>(&__val_)) _Tp(); }
+
+ constexpr expected(const expected& __other)
+ requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err>
+ : __has_val_(__other.__has_val_)
+ {
+ if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_);
+ else ::new (static_cast<void*>(&__err_)) _Err(__other.__err_);
+ }
+
+ constexpr expected(expected&& __other)
+ noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
+ requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
+ : __has_val_(__other.__has_val_)
+ {
+ if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_));
+ else ::new (static_cast<void*>(&__err_)) _Err(std::move(__other.__err_));
+ }
+
+ template<class _Up = _Tp>
+ requires (!__is_same(__decay(_Up), expected)) &&
+ (!__is_same(__decay(_Up), in_place_t)) &&
+ is_constructible_v<_Tp, _Up>
+ constexpr expected(_Up&& __val) : __has_val_(true) {
+ ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Up>(__val));
+ }
+
+ template<class _G>
+ requires is_constructible_v<_Err, const _G&>
+ constexpr expected(const unexpected<_G>& __e) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(__e.error());
+ }
+
+ template<class _G>
+ requires is_constructible_v<_Err, _G>
+ constexpr expected(unexpected<_G>&& __e) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(std::move(__e.error()));
+ }
+
+ template<class... _Args>
+ requires is_constructible_v<_Tp, _Args...>
+ constexpr explicit expected(in_place_t, _Args&&... __args) : __has_val_(true) {
+ ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...);
+ }
+
+ template<class... _Args>
+ requires is_constructible_v<_Err, _Args...>
+ constexpr explicit expected(unexpect_t, _Args&&... __args) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(std::forward<_Args>(__args)...);
+ }
+
+ // ── Destructor ───────────────────────��──────────────────────────────
+
+ constexpr ~expected()
+ requires is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>
+ = default;
+
+ constexpr ~expected()
+ requires (!(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>))
+ {
+ if (__has_val_) __val_.~_Tp();
+ else __err_.~_Err();
+ }
+
+ // ── Assignment ───────���───────────────────────────���──────────────────
+
+ constexpr expected& operator=(const expected& __other)
+ requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
+ is_copy_assignable_v<_Tp> && is_copy_assignable_v<_Err>
+ {
+ if (__has_val_ && __other.__has_val_) {
+ __val_ = __other.__val_;
+ } else if (!__has_val_ && !__other.__has_val_) {
+ __err_ = __other.__err_;
+ } else {
+ __destroy();
+ __has_val_ = __other.__has_val_;
+ if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(__other.__val_);
+ else ::new (static_cast<void*>(&__err_)) _Err(__other.__err_);
+ }
+ return *this;
+ }
+
+ constexpr expected& operator=(expected&& __other)
+ noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
+ requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
+ is_move_assignable_v<_Tp> && is_move_assignable_v<_Err>
+ {
+ if (__has_val_ && __other.__has_val_) {
+ __val_ = std::move(__other.__val_);
+ } else if (!__has_val_ && !__other.__has_val_) {
+ __err_ = std::move(__other.__err_);
+ } else {
+ __destroy();
+ __has_val_ = __other.__has_val_;
+ if (__has_val_) ::new (static_cast<void*>(&__val_)) _Tp(std::move(__other.__val_));
+ else ::new (static_cast<void*>(&__err_)) _Err(std::move(__other.__err_));
+ }
+ return *this;
+ }
+
+ // ── Observers ───────────────────────────────────────────────────────
+
+ _LIBBASTION_NODISCARD constexpr bool has_value() const noexcept { return __has_val_; }
+ _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __has_val_; }
+
+ _LIBBASTION_NODISCARD constexpr _Tp& operator*() & { return __val_; }
+ _LIBBASTION_NODISCARD constexpr const _Tp& operator*() const& { return __val_; }
+ _LIBBASTION_NODISCARD constexpr _Tp&& operator*() && { return std::move(__val_); }
+ _LIBBASTION_NODISCARD constexpr _Tp* operator->() { return &__val_; }
+ _LIBBASTION_NODISCARD constexpr const _Tp* operator->() const { return &__val_; }
+
+ _LIBBASTION_NODISCARD constexpr _Tp& value() & {
+ if (!__has_val_) _LIBBASTION_TRAP();
+ return __val_;
+ }
+ _LIBBASTION_NODISCARD constexpr const _Tp& value() const& {
+ if (!__has_val_) _LIBBASTION_TRAP();
+ return __val_;
+ }
+ _LIBBASTION_NODISCARD constexpr _Tp&& value() && {
+ if (!__has_val_) _LIBBASTION_TRAP();
+ return std::move(__val_);
+ }
+
+ _LIBBASTION_NODISCARD constexpr _Err& error() & { return __err_; }
+ _LIBBASTION_NODISCARD constexpr const _Err& error() const& { return __err_; }
+ _LIBBASTION_NODISCARD constexpr _Err&& error() && { return std::move(__err_); }
+
+ template<class _Up>
+ _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) const& {
+ return __has_val_ ? __val_ : static_cast<_Tp>(std::forward<_Up>(__default_val));
+ }
+ template<class _Up>
+ _LIBBASTION_NODISCARD constexpr _Tp value_or(_Up&& __default_val) && {
+ return __has_val_ ? std::move(__val_) : static_cast<_Tp>(std::forward<_Up>(__default_val));
+ }
+
+ // ── Monadic operations (C++23) ───────────────────────��──────────────
+
+ template<class _Fn>
+ constexpr auto and_then(_Fn&& __f) & {
+ if (__has_val_) return std::forward<_Fn>(__f)(__val_);
+ using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_)));
+ return _Result(unexpect, __err_);
+ }
+
+ template<class _Fn>
+ constexpr auto and_then(_Fn&& __f) const& {
+ if (__has_val_) return std::forward<_Fn>(__f)(__val_);
+ using _Result = __decay(decltype(std::forward<_Fn>(__f)(__val_)));
+ return _Result(unexpect, __err_);
+ }
+
+ template<class _Fn>
+ constexpr auto and_then(_Fn&& __f) && {
+ if (__has_val_) return std::forward<_Fn>(__f)(std::move(__val_));
+ using _Result = __decay(decltype(std::forward<_Fn>(__f)(std::move(__val_))));
+ return _Result(unexpect, std::move(__err_));
+ }
+
+ template<class _Fn>
+ constexpr auto transform(_Fn&& __f) & {
+ using _Up = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_)));
+ if (__has_val_) return expected<_Up, _Err>(std::forward<_Fn>(__f)(__val_));
+ return expected<_Up, _Err>(unexpect, __err_);
+ }
+
+ template<class _Fn>
+ constexpr auto transform(_Fn&& __f) const& {
+ using _Up = __remove_cvref(decltype(std::forward<_Fn>(__f)(__val_)));
+ if (__has_val_) return expected<_Up, _Err>(std::forward<_Fn>(__f)(__val_));
+ return expected<_Up, _Err>(unexpect, __err_);
+ }
+
+ template<class _Fn>
+ constexpr auto or_else(_Fn&& __f) & {
+ if (__has_val_) {
+ using _Result = __decay(decltype(std::forward<_Fn>(__f)(__err_)));
+ return _Result(__val_);
+ }
+ return std::forward<_Fn>(__f)(__err_);
+ }
+
+ template<class _Fn>
+ constexpr auto or_else(_Fn&& __f) const& {
+ if (__has_val_) {
+ using _Result = __decay(decltype(std::forward<_Fn>(__f)(__err_)));
+ return _Result(__val_);
+ }
+ return std::forward<_Fn>(__f)(__err_);
+ }
+
+ template<class _Fn>
+ constexpr auto transform_error(_Fn&& __f) & {
+ using _G = __remove_cvref(decltype(std::forward<_Fn>(__f)(__err_)));
+ if (__has_val_) return expected<_Tp, _G>(in_place, __val_);
+ return expected<_Tp, _G>(unexpect, std::forward<_Fn>(__f)(__err_));
+ }
+
+ template<class _Fn>
+ constexpr auto transform_error(_Fn&& __f) const& {
+ using _G = __remove_cvref(decltype(std::forward<_Fn>(__f)(__err_)));
+ if (__has_val_) return expected<_Tp, _G>(in_place, __val_);
+ return expected<_Tp, _G>(unexpect, std::forward<_Fn>(__f)(__err_));
+ }
+
+ // ── Modifiers ───────────────────────────────────────────────────────
+
+ template<class... _Args>
+ constexpr _Tp& emplace(_Args&&... __args) {
+ __destroy();
+ ::new (static_cast<void*>(&__val_)) _Tp(std::forward<_Args>(__args)...);
+ __has_val_ = true;
+ return __val_;
+ }
+
+private:
+ constexpr void __destroy() {
+ if (__has_val_) {
+ if constexpr (!is_trivially_destructible_v<_Tp>) __val_.~_Tp();
+ } else {
+ if constexpr (!is_trivially_destructible_v<_Err>) __err_.~_Err();
+ }
+ }
+
+ union {
+ _Tp __val_;
+ _Err __err_;
+ };
+ bool __has_val_;
+};
+
+// ── expected<void, E> specialization ────────────────────────────────────────
+
+template<class _Err>
+class expected<void, _Err> {
+public:
+ using value_type = void;
+ using error_type = _Err;
+ using unexpected_type = unexpected<_Err>;
+
+ constexpr expected() noexcept : __has_val_(true) {}
+
+ template<class _G>
+ requires is_constructible_v<_Err, const _G&>
+ constexpr expected(const unexpected<_G>& __e) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(__e.error());
+ }
+
+ template<class _G>
+ requires is_constructible_v<_Err, _G>
+ constexpr expected(unexpected<_G>&& __e) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(std::move(__e.error()));
+ }
+
+ constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
+
+ template<class... _Args>
+ requires is_constructible_v<_Err, _Args...>
+ constexpr explicit expected(unexpect_t, _Args&&... __args) : __has_val_(false) {
+ ::new (static_cast<void*>(&__err_)) _Err(std::forward<_Args>(__args)...);
+ }
+
+ constexpr ~expected() requires is_trivially_destructible_v<_Err> = default;
+ constexpr ~expected() requires (!is_trivially_destructible_v<_Err>) {
+ if (!__has_val_) __err_.~_Err();
+ }
+
+ _LIBBASTION_NODISCARD constexpr bool has_value() const noexcept { return __has_val_; }
+ _LIBBASTION_NODISCARD constexpr explicit operator bool() const noexcept { return __has_val_; }
+
+ constexpr void operator*() const noexcept {}
+ constexpr void value() const { if (!__has_val_) _LIBBASTION_TRAP(); }
+
+ _LIBBASTION_NODISCARD constexpr _Err& error() & { return __err_; }
+ _LIBBASTION_NODISCARD constexpr const _Err& error() const& { return __err_; }
+ _LIBBASTION_NODISCARD constexpr _Err&& error() && { return std::move(__err_); }
+
+ constexpr void emplace() noexcept {
+ if (!__has_val_) {
+ if constexpr (!is_trivially_destructible_v<_Err>) __err_.~_Err();
+ __has_val_ = true;
+ }
+ }
+
+private:
+ union {
+ char __empty_;
+ _Err __err_;
+ };
+ bool __has_val_;
+};
+
+// ── Comparison ──────────────────────────────────────────────────────────────
+
+template<class _T1, class _E1, class _T2, class _E2>
+_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const expected<_T2, _E2>& __y) {
+ if (__x.has_value() != __y.has_value()) return false;
+ if (__x.has_value()) return *__x == *__y;
+ return __x.error() == __y.error();
+}
+
+template<class _T1, class _E1, class _T2>
+_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const _T2& __y) {
+ return __x.has_value() && *__x == __y;
+}
+
+template<class _T1, class _E1, class _E2>
+_LIBBASTION_NODISCARD constexpr bool operator==(const expected<_T1, _E1>& __x, const unexpected<_E2>& __y) {
+ return !__x.has_value() && __x.error() == __y.error();
+}
+
+_LIBBASTION_END_NAMESPACE_STD
+
+#endif // _LIBBASTION_EXPECTED_EXPECTED_H