// expected standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef _EXPECTED_
#define _EXPECTED_
#include <yvals.h>
#if _STL_COMPILER_PREPROCESSOR
#if !_HAS_CXX23
_EMIT_STL_WARNING(STL4038, "The contents of <expected> are available only with C++23 or later.");
#else // ^^^ !_HAS_CXX23 / _HAS_CXX23 vvv
#include <exception>
#include <initializer_list>
#include <type_traits>
#include <xutility>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

_STD_BEGIN

_EXPORT_STD template <class _Err>
class _NODISCARD unexpected;

template <class _Err>
struct _Check_unexpected_argument : true_type {
    static_assert(is_object_v<_Err>, "E must be an object type. (N4950 [expected.un.general]/2)");
    static_assert(!is_array_v<_Err>, "E must not be an array type. (N4950 [expected.un.general]/2)");
    static_assert(!is_const_v<_Err>, "E must not be const. (N4950 [expected.un.general]/2)");
    static_assert(!is_volatile_v<_Err>, "E must not be volatile. (N4950 [expected.un.general]/2)");
    static_assert(!_Is_specialization_v<_Err, unexpected>,
        "E must not be a specialization of unexpected. (N4950 [expected.un.general]/2)");
};

// [expected.un.general]
_EXPORT_STD template <class _Err>
class _NODISCARD unexpected {
    static_assert(_Check_unexpected_argument<_Err>::value);

    template <class _Ty, class _Err2>
    friend class expected;

public:
    // [expected.un.cons]
    template <class _UError = _Err>
        requires (!is_same_v<remove_cvref_t<_UError>, unexpected> && !is_same_v<remove_cvref_t<_UError>, in_place_t>
                  && is_constructible_v<_Err, _UError>)
    constexpr explicit unexpected(_UError&& _Unex) noexcept(is_nothrow_constructible_v<_Err, _UError>) // strengthened
        : _Unexpected(_STD forward<_UError>(_Unex)) {}

    template <class... _Args>
        requires is_constructible_v<_Err, _Args...>
    constexpr explicit unexpected(in_place_t, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
        : _Unexpected(_STD forward<_Args>(_Vals)...) {}

    template <class _Uty, class... _Args>
        requires is_constructible_v<_Err, initializer_list<_Uty>&, _Args...>
    constexpr explicit unexpected(in_place_t, initializer_list<_Uty> _Ilist, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Uty>&, _Args...>) // strengthened
        : _Unexpected(_Ilist, _STD forward<_Args>(_Vals)...) {}

    // [expected.un.obs]
    _NODISCARD constexpr const _Err& error() const& noexcept {
        return _Unexpected;
    }
    _NODISCARD constexpr _Err& error() & noexcept {
        return _Unexpected;
    }
    _NODISCARD constexpr const _Err&& error() const&& noexcept {
        return _STD move(_Unexpected);
    }
    _NODISCARD constexpr _Err&& error() && noexcept {
        return _STD move(_Unexpected);
    }

    // [expected.un.swap]
    constexpr void swap(unexpected& _Other) noexcept(is_nothrow_swappable_v<_Err>) {
        static_assert(is_swappable_v<_Err>, "E must be swappable");
        using _STD swap;
        swap(_Unexpected, _Other._Unexpected); // intentional ADL
    }

    friend constexpr void swap(unexpected& _Left, unexpected& _Right) noexcept(is_nothrow_swappable_v<_Err>)
        requires is_swappable<_Err>::value // TRANSITION, /permissive needs ::value
    {
        _Left.swap(_Right);
    }

    // [expected.un.eq]
    template <class _UErr>
    _NODISCARD friend constexpr bool operator==(const unexpected& _Left, const unexpected<_UErr>& _Right)
        noexcept(noexcept(_STD _Fake_copy_init<bool>(_Left._Unexpected == _Right.error()))) /* strengthened */ {
        return _Left._Unexpected == _Right.error();
    }

private:
    _Err _Unexpected;
};

template <class _Err>
unexpected(_Err) -> unexpected<_Err>;

_EXPORT_STD template <class _Err>
class _NODISCARD bad_expected_access;

template <>
class _NODISCARD bad_expected_access<void> : public exception {
public:
    _NODISCARD const char* __CLR_OR_THIS_CALL what() const noexcept override {
        return "Bad expected access";
    }

protected:
    bad_expected_access()                                      = default;
    bad_expected_access(const bad_expected_access&)            = default;
    bad_expected_access(bad_expected_access&&)                 = default;
    bad_expected_access& operator=(const bad_expected_access&) = default;
    bad_expected_access& operator=(bad_expected_access&&)      = default;

#if !_HAS_EXCEPTIONS
    void _Doraise() const override { // perform class-specific exception handling
        _RAISE(*this);
    }
#endif // !_HAS_EXCEPTIONS
};

_EXPORT_STD template <class _Err>
class _NODISCARD bad_expected_access : public bad_expected_access<void> {
public:
    explicit bad_expected_access(_Err _Unex) noexcept(is_nothrow_move_constructible_v<_Err>) // strengthened
        : _Unexpected(_STD move(_Unex)) {}

    _NODISCARD const _Err& error() const& noexcept {
        return _Unexpected;
    }
    _NODISCARD _Err& error() & noexcept {
        return _Unexpected;
    }
    _NODISCARD const _Err&& error() const&& noexcept {
        return _STD move(_Unexpected);
    }
    _NODISCARD _Err&& error() && noexcept {
        return _STD move(_Unexpected);
    }

private:
    _Err _Unexpected;
};

_EXPORT_STD struct unexpect_t {
    explicit unexpect_t() = default;
};

_EXPORT_STD inline constexpr unexpect_t unexpect{};

struct _Construct_expected_from_invoke_result_tag {
    explicit _Construct_expected_from_invoke_result_tag() = default;
};

template <class _Fn, class... _Tys>
concept _Is_invoke_constructible = requires(_Fn&& _Func, _Tys&&... _Vals) {
    static_cast<remove_cvref_t<invoke_result_t<_Fn, _Tys...>>>(
        _STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Tys>(_Vals)...));
};

template <class _Ty>
struct _Check_expected_argument : true_type {
    static_assert(!is_reference_v<_Ty>, "T must not be a reference type. (N4950 [expected.object.general]/2)");
    static_assert(!is_function_v<_Ty>, "T must not be a function type. (N4950 [expected.object.general]/2)");
    static_assert(!is_array_v<_Ty>, "T must not be an array type. (N4950 [expected.object.general]/2)");
    static_assert(!is_same_v<remove_cv_t<_Ty>, in_place_t>,
        "T must not be (possibly cv-qualified) in_place_t. (N4950 [expected.object.general]/2)");
    static_assert(!is_same_v<remove_cv_t<_Ty>, unexpect_t>,
        "T must not be (possibly cv-qualified) unexpect_t. (N4950 [expected.object.general]/2)");
    static_assert(!_Is_specialization_v<remove_cv_t<_Ty>, unexpected>,
        "T must not be a (possibly cv-qualified) specialization of unexpected. (N4950 [expected.object.general]/2)");
};

template <class _Ty, class _Err>
concept _Expected_binary_copy_assignable =
    is_copy_assignable_v<_Ty> && is_copy_constructible_v<_Ty> //
    && is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>
    && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>);

template <class _Ty, class _Err>
concept _Expected_binary_move_assignable =
    is_move_assignable_v<_Ty> && is_move_constructible_v<_Ty> //
    && is_move_assignable_v<_Err> && is_move_constructible_v<_Err>
    && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>);

template <class _Type> // used with both _Ty and _Err
concept _Trivially_copy_constructible_assignable_destructible =
    is_trivially_copy_constructible_v<_Type> && is_trivially_copy_assignable_v<_Type>
    && is_trivially_destructible_v<_Type>;

template <class _Type> // used with both _Ty and _Err
concept _Trivially_move_constructible_assignable_destructible =
    is_trivially_move_constructible_v<_Type> && is_trivially_move_assignable_v<_Type>
    && is_trivially_destructible_v<_Type>;

_EXPORT_STD template <class _Ty, class _Err>
class _NODISCARD expected {
private:
    static_assert(_Check_expected_argument<_Ty>::value);
    static_assert(_Check_unexpected_argument<_Err>::value);

    template <class _UTy, class _UErr>
    friend class expected;

    template <class _Uty, class _UErr>
    static constexpr bool _Allow_unwrapping = disjunction_v<is_same<remove_cv_t<_Ty>, bool>,
                                                  negation<disjunction<is_constructible<_Ty, expected<_Uty, _UErr>&>, //
                                                      is_constructible<_Ty, expected<_Uty, _UErr>>, //
                                                      is_constructible<_Ty, const expected<_Uty, _UErr>&>, //
                                                      is_constructible<_Ty, const expected<_Uty, _UErr>>, //
                                                      is_convertible<expected<_Uty, _UErr>&, _Ty>, //
                                                      is_convertible<expected<_Uty, _UErr>&&, _Ty>, //
                                                      is_convertible<const expected<_Uty, _UErr>&, _Ty>, //
                                                      is_convertible<const expected<_Uty, _UErr>&&, _Ty>>>>
                                           && !is_constructible_v<unexpected<_Err>, expected<_Uty, _UErr>&>
                                           && !is_constructible_v<unexpected<_Err>, expected<_Uty, _UErr>>
                                           && !is_constructible_v<unexpected<_Err>, const expected<_Uty, _UErr>&>
                                           && !is_constructible_v<unexpected<_Err>, const expected<_Uty, _UErr>>;

public:
    using value_type      = _Ty;
    using error_type      = _Err;
    using unexpected_type = unexpected<_Err>;

    template <class _Uty>
    using rebind = expected<_Uty, error_type>;

    // [expected.object.cons]
    constexpr expected() noexcept(is_nothrow_default_constructible_v<_Ty>) // strengthened
        requires is_default_constructible_v<_Ty>
        : _Value(), _Has_value(true) {}

    constexpr expected(const expected& _Other)
        noexcept(is_nothrow_copy_constructible_v<_Ty> && is_nothrow_copy_constructible_v<_Err>) // strengthened
        requires (!(is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_constructible_v<_Err>)
                  && is_copy_constructible_v<_Ty> && is_copy_constructible_v<_Err>)
        : _Has_value(_Other._Has_value) {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Value), _Other._Value);
        } else {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
        }
    }

    expected(const expected&)
        requires is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_constructible_v<_Err>
    = default;

    expected(const expected&) = delete;

    constexpr expected(expected&& _Other)
        noexcept(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_constructible_v<_Err>)
        requires (!(is_trivially_move_constructible_v<_Ty> && is_trivially_move_constructible_v<_Err>)
                  && is_move_constructible_v<_Ty> && is_move_constructible_v<_Err>)
        : _Has_value(_Other._Has_value) {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Value), _STD move(_Other._Value));
        } else {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
        }
    }

    expected(expected&&)
        requires is_trivially_move_constructible_v<_Ty> && is_trivially_move_constructible_v<_Err>
    = default;

    template <class _Uty, class _UErr>
        requires _Different_from<expected<_Uty, _UErr>, expected> && is_constructible_v<_Ty, const _Uty&>
              && is_constructible_v<_Err, const _UErr&> && _Allow_unwrapping<_Uty, _UErr>
    constexpr explicit(!is_convertible_v<const _Uty&, _Ty> || !is_convertible_v<const _UErr&, _Err>)
        expected(const expected<_Uty, _UErr>& _Other)
            noexcept(is_nothrow_constructible_v<_Ty, const _Uty&>
                     && is_nothrow_constructible_v<_Err, const _UErr&>) // strengthened
        : _Has_value(_Other._Has_value) {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Value), _Other._Value);
        } else {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
        }
    }

    template <class _Uty, class _UErr>
        requires _Different_from<expected<_Uty, _UErr>, expected> && is_constructible_v<_Ty, _Uty>
              && is_constructible_v<_Err, _UErr> && _Allow_unwrapping<_Uty, _UErr>
    constexpr explicit(!is_convertible_v<_Uty, _Ty> || !is_convertible_v<_UErr, _Err>)
        expected(expected<_Uty, _UErr>&& _Other)
            noexcept(is_nothrow_constructible_v<_Ty, _Uty> && is_nothrow_constructible_v<_Err, _UErr>) // strengthened
        : _Has_value(_Other._Has_value) {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Value), _STD move(_Other._Value));
        } else {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
        }
    }

    template <class _Uty = remove_cv_t<_Ty>>
        requires (!is_same_v<remove_cvref_t<_Uty>, in_place_t> && !is_same_v<remove_cvref_t<_Uty>, expected>
                     && !_Is_specialization_v<remove_cvref_t<_Uty>, unexpected>
                     && (!is_same_v<remove_cv_t<_Ty>, bool>
#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10655311
                         || !_Is_specialization_v<remove_cvref_t<_Uty>, expected>
#else // ^^^ no workaround / workaround vvv
                         || !_Is_specialization_v<remove_cvref_t<_Uty>, _STD expected>
#endif // ^^^ workaround ^^^
                         )
                     && is_constructible_v<_Ty, _Uty>)
    constexpr explicit(!is_convertible_v<_Uty, _Ty>) expected(_Uty&& _Other)
        noexcept(is_nothrow_constructible_v<_Ty, _Uty>) // strengthened
        : _Value(_STD forward<_Uty>(_Other)), _Has_value(true) {
    }

    template <class _UErr>
        requires is_constructible_v<_Err, const _UErr&>
    constexpr explicit(!is_convertible_v<const _UErr&, _Err>) expected(const unexpected<_UErr>& _Other) //
        noexcept(is_nothrow_constructible_v<_Err, const _UErr&>) // strengthened
        : _Unexpected(_Other._Unexpected), _Has_value(false) {}

    template <class _UErr>
        requires is_constructible_v<_Err, _UErr>
    constexpr explicit(!is_convertible_v<_UErr, _Err>) expected(unexpected<_UErr>&& _Other) //
        noexcept(is_nothrow_constructible_v<_Err, _UErr>) // strengthened
        : _Unexpected(_STD move(_Other._Unexpected)), _Has_value(false) {}

    template <class... _Args>
        requires is_constructible_v<_Ty, _Args...>
    constexpr explicit expected(in_place_t, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Ty, _Args...>) // strengthened
        : _Value(_STD forward<_Args>(_Vals)...), _Has_value(true) {}

    template <class _Uty, class... _Args>
        requires is_constructible_v<_Ty, initializer_list<_Uty>&, _Args...>
    constexpr explicit expected(in_place_t, initializer_list<_Uty> _Ilist, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Ty, initializer_list<_Uty>&, _Args...>) // strengthened
        : _Value(_Ilist, _STD forward<_Args>(_Vals)...), _Has_value(true) {}

    template <class... _Args>
        requires is_constructible_v<_Err, _Args...>
    constexpr explicit expected(unexpect_t, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
        : _Unexpected(_STD forward<_Args>(_Vals)...), _Has_value(false) {}

    template <class _Uty, class... _Args>
        requires is_constructible_v<_Err, initializer_list<_Uty>&, _Args...>
    constexpr explicit expected(unexpect_t, initializer_list<_Uty> _Ilist, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Uty>&, _Args...>) // strengthened
        : _Unexpected(_Ilist, _STD forward<_Args>(_Vals)...), _Has_value(false) {}

    // [expected.object.dtor]
    constexpr ~expected()
#ifndef __clang__ // TRANSITION, LLVM-59854
        noexcept
#endif // ^^^ no workaround ^^^
    {
        if (_Has_value) {
            if constexpr (!is_trivially_destructible_v<_Ty>) {
                _Value.~_Ty();
            }
        } else {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
        }
    }

    ~expected()
        requires is_trivially_destructible_v<_Ty> && is_trivially_destructible_v<_Err>
    = default;

    // [expected.object.assign]
    template <class _Uty>
        requires is_nothrow_move_constructible_v<_Uty>
    struct _NODISCARD _GuardTy {
        constexpr _GuardTy(_Uty* _Target_, _Uty* _Tmp_) noexcept : _Target(_Target_), _Tmp(_Tmp_) {}
        constexpr ~_GuardTy() noexcept {
            if (_Target) {
                _STD construct_at(_Target, _STD move(*_Tmp));
            }
        }
        _Uty* _Target;
        _Uty* _Tmp;
    };

    template <class _First, class _Second, class... _Args>
    static constexpr void _Reinit_expected(_First& _New_val, _Second& _Old_val, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_First, _Args...>) /* strengthened */ {
        if constexpr (is_nothrow_constructible_v<_First, _Args...>) {
            if constexpr (!is_trivially_destructible_v<_Second>) {
                _Old_val.~_Second();
            }
            _STD construct_at(_STD addressof(_New_val), _STD forward<_Args>(_Vals)...);
        } else if constexpr (is_nothrow_move_constructible_v<_First>) {
            _First _Tmp(_STD forward<_Args>(_Vals)...);
            if constexpr (!is_trivially_destructible_v<_Second>) {
                _Old_val.~_Second();
            }
            _STD construct_at(_STD addressof(_New_val), _STD move(_Tmp));
        } else {
            _Second _Tmp(_STD move(_Old_val));
            if constexpr (!is_trivially_destructible_v<_Second>) {
                _Old_val.~_Second();
            }

            _GuardTy<_Second> _Guard{_STD addressof(_Old_val), _STD addressof(_Tmp)};
            _STD construct_at(_STD addressof(_New_val), _STD forward<_Args>(_Vals)...);
            _Guard._Target = nullptr;
        }
    }

    constexpr expected& operator=(const expected& _Other)
        noexcept(is_nothrow_copy_constructible_v<_Ty> && is_nothrow_copy_constructible_v<_Err>
                 && is_nothrow_copy_assignable_v<_Ty> && is_nothrow_copy_assignable_v<_Err>) // strengthened
        requires _Expected_binary_copy_assignable<_Ty, _Err>
    {
        if (_Has_value && _Other._Has_value) {
            _Value = _Other._Value;
        } else if (_Has_value) {
            _Reinit_expected(_Unexpected, _Value, _Other._Unexpected);
        } else if (_Other._Has_value) {
            _Reinit_expected(_Value, _Unexpected, _Other._Value);
        } else {
            _Unexpected = _Other._Unexpected;
        }

        _Has_value = _Other._Has_value;
        return *this;
    }

    expected& operator=(const expected&)
        requires _Expected_binary_copy_assignable<_Ty, _Err>
                  && _Trivially_copy_constructible_assignable_destructible<_Ty>
                  && _Trivially_copy_constructible_assignable_destructible<_Err>
    = default;

    expected& operator=(const expected&) = delete;

    constexpr expected& operator=(expected&& _Other)
        noexcept(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_constructible_v<_Err>
                 && is_nothrow_move_assignable_v<_Ty> && is_nothrow_move_assignable_v<_Err>)
        requires _Expected_binary_move_assignable<_Ty, _Err>
    {
        if (_Has_value && _Other._Has_value) {
            _Value = _STD move(_Other._Value);
        } else if (_Has_value) {
            _Reinit_expected(_Unexpected, _Value, _STD move(_Other._Unexpected));
        } else if (_Other._Has_value) {
            _Reinit_expected(_Value, _Unexpected, _STD move(_Other._Value));
        } else {
            _Unexpected = _STD move(_Other._Unexpected);
        }

        _Has_value = _Other._Has_value;
        return *this;
    }

    expected& operator=(expected&&)
        requires _Expected_binary_move_assignable<_Ty, _Err>
                  && _Trivially_move_constructible_assignable_destructible<_Ty>
                  && _Trivially_move_constructible_assignable_destructible<_Err>
    = default;

    template <class _Uty = remove_cv_t<_Ty>>
        requires (!is_same_v<remove_cvref_t<_Uty>, expected> && !_Is_specialization_v<remove_cvref_t<_Uty>, unexpected>
                  && is_constructible_v<_Ty, _Uty> && is_assignable_v<_Ty&, _Uty>
                  && (is_nothrow_constructible_v<_Ty, _Uty> || is_nothrow_move_constructible_v<_Ty>
                      || is_nothrow_move_constructible_v<_Err>) )
    constexpr expected& operator=(_Uty&& _Other)
        noexcept(is_nothrow_constructible_v<_Ty, _Uty> && is_nothrow_assignable_v<_Ty&, _Uty>) /* strengthened */ {
        if (_Has_value) {
            _Value = _STD forward<_Uty>(_Other);
        } else {
            _Reinit_expected(_Value, _Unexpected, _STD forward<_Uty>(_Other));
            _Has_value = true;
        }

        return *this;
    }

    template <class _UErr>
        requires (is_constructible_v<_Err, const _UErr&> && is_assignable_v<_Err&, const _UErr&>
                  && (is_nothrow_constructible_v<_Err, const _UErr&> || is_nothrow_move_constructible_v<_Ty>
                      || is_nothrow_move_constructible_v<_Err>) )
    constexpr expected& operator=(const unexpected<_UErr>& _Other)
        noexcept(is_nothrow_constructible_v<_Err, const _UErr&>
                 && is_nothrow_assignable_v<_Err&, const _UErr&>) /* strengthened */ {
        if (_Has_value) {
            _Reinit_expected(_Unexpected, _Value, _Other._Unexpected);
            _Has_value = false;
        } else {
            _Unexpected = _Other._Unexpected;
        }

        return *this;
    }

    template <class _UErr>
        requires (is_constructible_v<_Err, _UErr> && is_assignable_v<_Err&, _UErr>
                  && (is_nothrow_constructible_v<_Err, _UErr> || is_nothrow_move_constructible_v<_Ty>
                      || is_nothrow_move_constructible_v<_Err>) )
    constexpr expected& operator=(unexpected<_UErr>&& _Other)
        noexcept(is_nothrow_constructible_v<_Err, _UErr> && is_nothrow_assignable_v<_Err&, _UErr>) /* strengthened */ {
        if (_Has_value) {
            _Reinit_expected(_Unexpected, _Value, _STD move(_Other._Unexpected));
            _Has_value = false;
        } else {
            _Unexpected = _STD move(_Other._Unexpected);
        }

        return *this;
    }

    template <class... _Args>
        requires is_nothrow_constructible_v<_Ty, _Args...>
    constexpr _Ty& emplace(_Args&&... _Vals) noexcept {
        if (_Has_value) {
            if constexpr (!is_trivially_destructible_v<_Ty>) {
                _Value.~_Ty();
            }
        } else {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value = true;
        }

        return *_STD construct_at(_STD addressof(_Value), _STD forward<_Args>(_Vals)...);
    }

    template <class _Uty, class... _Args>
        requires is_nothrow_constructible_v<_Ty, initializer_list<_Uty>&, _Args...>
    constexpr _Ty& emplace(initializer_list<_Uty> _Ilist, _Args&&... _Vals) noexcept {
        if (_Has_value) {
            if constexpr (!is_trivially_destructible_v<_Ty>) {
                _Value.~_Ty();
            }
        } else {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value = true;
        }

        return *_STD construct_at(_STD addressof(_Value), _Ilist, _STD forward<_Args>(_Vals)...);
    }

    // [expected.object.swap]
    constexpr void swap(expected& _Other)
        noexcept(is_nothrow_move_constructible_v<_Ty> && is_nothrow_swappable_v<_Ty>
                 && is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
        requires is_swappable_v<_Ty> && is_swappable_v<_Err> //
              && is_move_constructible_v<_Ty> && is_move_constructible_v<_Err>
              && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>)
    {
        using _STD swap;
        if (_Has_value && _Other._Has_value) {
            swap(_Value, _Other._Value); // intentional ADL
        } else if (_Has_value) {
            if constexpr (is_nothrow_move_constructible_v<_Err>) {
                _Err _Tmp(_STD move(_Other._Unexpected));
                if constexpr (!is_trivially_destructible_v<_Err>) {
                    _Other._Unexpected.~_Err();
                }

                if constexpr (is_nothrow_move_constructible_v<_Ty>) {
                    _STD construct_at(_STD addressof(_Other._Value), _STD move(_Value));
                } else {
                    _GuardTy<_Err> _Guard{_STD addressof(_Other._Unexpected), _STD addressof(_Tmp)};
                    _STD construct_at(_STD addressof(_Other._Value), _STD move(_Value));
                    _Guard._Target = nullptr;
                }

                if constexpr (!is_trivially_destructible_v<_Ty>) {
                    _Value.~_Ty();
                }
                _STD construct_at(_STD addressof(_Unexpected), _STD move(_Tmp));
            } else {
                _Ty _Tmp(_STD move(_Value));
                if constexpr (!is_trivially_destructible_v<_Ty>) {
                    _Value.~_Ty();
                }

                _GuardTy<_Ty> _Guard{_STD addressof(_Value), _STD addressof(_Tmp)};
                _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
                _Guard._Target = nullptr;

                if constexpr (!is_trivially_destructible_v<_Err>) {
                    _Other._Unexpected.~_Err();
                }
                _STD construct_at(_STD addressof(_Other._Value), _STD move(_Tmp));
            }

            _Has_value        = false;
            _Other._Has_value = true;
        } else if (_Other._Has_value) {
            _Other.swap(*this);
        } else {
            swap(_Unexpected, _Other._Unexpected); // intentional ADL
        }
    }

    friend constexpr void swap(expected& _Lhs, expected& _Rhs)
        noexcept(is_nothrow_move_constructible_v<_Ty> && is_nothrow_swappable_v<_Ty>
                 && is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
        requires is_swappable<_Ty>::value && is_swappable<_Err>::value // TRANSITION, /permissive needs ::value
              && is_move_constructible_v<_Ty> && is_move_constructible_v<_Err>
              && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>)
    {
        _Lhs.swap(_Rhs);
    }

    // [expected.object.obs]
    _NODISCARD constexpr const _Ty* operator->() const noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator->() called on a std::expected that contains an error, not a value");
#endif

        return _STD addressof(_Value);
    }
    _NODISCARD constexpr _Ty* operator->() noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator->() called on a std::expected that contains an error, not a value");
#endif

        return _STD addressof(_Value);
    }

    _NODISCARD constexpr const _Ty& operator*() const& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value");
#endif

        return _Value;
    }
    _NODISCARD constexpr _Ty& operator*() & noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value");
#endif

        return _Value;
    }
    _NODISCARD constexpr const _Ty&& operator*() const&& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value");
#endif

        return _STD move(_Value);
    }
    _NODISCARD constexpr _Ty&& operator*() && noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value");
#endif

        return _STD move(_Value);
    }

    _NODISCARD constexpr explicit operator bool() const noexcept {
        return _Has_value;
    }
    _NODISCARD constexpr bool has_value() const noexcept {
        return _Has_value;
    }

    _NODISCARD constexpr const _Ty& value() const& {
        if (_Has_value) {
            return _Value;
        }

        _Throw_bad_expected_access_lv();
    }
    _NODISCARD constexpr _Ty& value() & {
        if (_Has_value) {
            return _Value;
        }

        _Throw_bad_expected_access_lv();
    }
    _NODISCARD constexpr const _Ty&& value() const&& {
        // TRANSITION, DevCom-1638273 and LLVM-53224
        static_assert(
            is_copy_constructible_v<_Err>, "is_copy_constructible_v<E> must be true. N4950 [expected.object.obs]/11");
        static_assert(is_constructible_v<_Err, const _Err&&>,
            "is_constructible_v<E, const E&&> must be true. N4950 [expected.object.obs]/11");

        if (_Has_value) {
            return _STD move(_Value);
        }

        _Throw_bad_expected_access_rv();
    }
    _NODISCARD constexpr _Ty&& value() && {
        // TRANSITION, DevCom-1638273 and LLVM-53224
        static_assert(
            is_copy_constructible_v<_Err>, "is_copy_constructible_v<E> must be true. N4950 [expected.object.obs]/11");
        static_assert(
            is_move_constructible_v<_Err>, "is_constructible_v<E, E&&> must be true. N4950 [expected.object.obs]/11");

        if (_Has_value) {
            return _STD move(_Value);
        }

        _Throw_bad_expected_access_rv();
    }

    _NODISCARD constexpr const _Err& error() const& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _Unexpected;
    }
    _NODISCARD constexpr _Err& error() & noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _Unexpected;
    }
    _NODISCARD constexpr const _Err&& error() const&& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _STD move(_Unexpected);
    }
    _NODISCARD constexpr _Err&& error() && noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _STD move(_Unexpected);
    }

    template <class _Uty = remove_cv_t<_Ty>>
    _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) const& noexcept(
        is_nothrow_convertible_v<const _Ty&, remove_cv_t<_Ty>>
        && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ {
        static_assert(is_convertible_v<const _Ty&, remove_cv_t<_Ty>>,
            "is_convertible_v<const T&, remove_cv_t<T>> must be true. "
            "(N5001 [expected.object.obs]/18 as modified by LWG-3424)");
        static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>,
            "is_convertible_v<U, remove_cv_t<T>> must be true. "
            "(N5001 [expected.object.obs]/18 as modified by LWG-3424)");

        if (_Has_value) {
            return _Value;
        } else {
            return static_cast<remove_cv_t<_Ty>>(_STD forward<_Uty>(_Other));
        }
    }
    template <class _Uty = remove_cv_t<_Ty>>
    _NODISCARD constexpr remove_cv_t<_Ty> value_or(_Uty&& _Other) && noexcept(
        is_nothrow_convertible_v<_Ty, remove_cv_t<_Ty>>
        && is_nothrow_convertible_v<_Uty, remove_cv_t<_Ty>>) /* strengthened */ {
        static_assert(is_convertible_v<_Ty, remove_cv_t<_Ty>>,
            "is_convertible_v<T, remove_cv_t<T>> must be true. "
            "(N5001 [expected.object.obs]/20 as modified by LWG-3424)");
        static_assert(is_convertible_v<_Uty, remove_cv_t<_Ty>>,
            "is_convertible_v<U, remove_cv_t<T>> must be true. "
            "(N5001 [expected.object.obs]/20 as modified by LWG-3424)");

        if (_Has_value) {
            return _STD move(_Value);
        } else {
            return static_cast<remove_cv_t<_Ty>>(_STD forward<_Uty>(_Other));
        }
    }

    template <class _Uty = _Err>
    _NODISCARD constexpr _Err error_or(_Uty&& _Other) const& noexcept(
        is_nothrow_copy_constructible_v<_Err> && is_nothrow_convertible_v<_Uty, _Err>) /* strengthened */ {
        static_assert(
            is_copy_constructible_v<_Err>, "is_copy_constructible_v<E> must be true. (N4950 [expected.object.obs]/22)");
        static_assert(
            is_convertible_v<_Uty, _Err>, "is_convertible_v<G, E> must be true. (N4950 [expected.object.obs]/22)");

        if (_Has_value) {
            return _STD forward<_Uty>(_Other);
        } else {
            return _Unexpected;
        }
    }

    template <class _Uty = _Err>
    _NODISCARD constexpr _Err error_or(_Uty&& _Other) && noexcept(
        is_nothrow_move_constructible_v<_Err> && is_nothrow_convertible_v<_Uty, _Err>) /* strengthened */ {
        static_assert(
            is_move_constructible_v<_Err>, "is_move_constructible_v<E> must be true. (N4950 [expected.object.obs]/24)");
        static_assert(
            is_convertible_v<_Uty, _Err>, "is_convertible_v<G, E> must be true. (N4950 [expected.object.obs]/24)");

        if (_Has_value) {
            return _STD forward<_Uty>(_Other);
        } else {
            return _STD move(_Unexpected);
        }
    }

    // [expected.object.monadic]
    template <class _Fn>
        requires is_constructible_v<_Err, _Err&>
    constexpr auto and_then(_Fn&& _Func) & {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Ty&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/3)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<T, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.object.monadic]/3)");

        if (_Has_value) {
            return _STD invoke(_STD forward<_Fn>(_Func), _Value);
        } else {
            return _Uty{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Err>
    constexpr auto and_then(_Fn&& _Func) const& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Ty&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/3)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<T, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.object.monadic]/3)");

        if (_Has_value) {
            return _STD invoke(_STD forward<_Fn>(_Func), _Value);
        } else {
            return _Uty{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Err>
    constexpr auto and_then(_Fn&& _Func) && {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Ty>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/7)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<T, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.object.monadic]/7)");

        if (_Has_value) {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Value));
        } else {
            return _Uty{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, const _Err>
    constexpr auto and_then(_Fn&& _Func) const&& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Ty>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/7)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<T, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.object.monadic]/7)");

        if (_Has_value) {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Value));
        } else {
            return _Uty{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Ty, _Ty&>
    constexpr auto or_else(_Fn&& _Func) & {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Err&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/11)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<T, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.object.monadic]/11)");

        if (_Has_value) {
            return _Uty{in_place, _Value};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _Unexpected);
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Ty>
    constexpr auto or_else(_Fn&& _Func) const& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Err&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/11)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<T, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.object.monadic]/11)");

        if (_Has_value) {
            return _Uty{in_place, _Value};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _Unexpected);
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Ty>
    constexpr auto or_else(_Fn&& _Func) && {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Err>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/15)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<T, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.object.monadic]/15)");

        if (_Has_value) {
            return _Uty{in_place, _STD move(_Value)};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Unexpected));
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Ty, const _Ty>
    constexpr auto or_else(_Fn&& _Func) const&& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Err>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<T, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.object.monadic]/15)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<T, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.object.monadic]/15)");

        if (_Has_value) {
            return _Uty{in_place, _STD move(_Value)};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Unexpected));
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, _Err&>
    constexpr auto transform(_Fn&& _Func) & {
        static_assert(invocable<_Fn, _Ty&>, "expected<T, E>::transform(F) requires that F is invocable with T. "
                                            "(N4950 [expected.object.monadic]/19)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Ty&>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn, _Ty&>,
                "expected<T, E>::transform(F) requires that the return type of F is constructible with the result of "
                "invoking f. (N4950 [expected.object.monadic]/19)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD invoke(_STD forward<_Fn>(_Func), _Value);
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{
                    _Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func), _Value};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Err>
    constexpr auto transform(_Fn&& _Func) const& {
        static_assert(invocable<_Fn, const _Ty&>, "expected<T, E>::transform(F) requires that F is invocable with T. "
                                                  "(N4950 [expected.object.monadic]/19)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Ty&>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn, const _Ty&>,
                "expected<T, E>::transform(F) requires that the return type of F is constructible with the result of "
                "invoking f. (N4950 [expected.object.monadic]/19)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD invoke(_STD forward<_Fn>(_Func), _Value);
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{
                    _Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func), _Value};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Err>
    constexpr auto transform(_Fn&& _Func) && {
        static_assert(invocable<_Fn, _Ty>, "expected<T, E>::transform(F) requires that F is invocable with T. "
                                           "(N4950 [expected.object.monadic]/23)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Ty>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn, _Ty>,
                "expected<T, E>::transform(F) requires that the return type of F is constructible with the result of "
                "invoking f. (N4950 [expected.object.monadic]/23)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Value));
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{
                    _Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func), _STD move(_Value)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, const _Err>
    constexpr auto transform(_Fn&& _Func) const&& {
        static_assert(invocable<_Fn, const _Ty>, "expected<T, E>::transform(F) requires that F is invocable with T. "
                                                 "(N4950 [expected.object.monadic]/23)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Ty>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn, const _Ty>,
                "expected<T, E>::transform(F) requires that the return type of F is constructible with the result of "
                "invoking f. (N4950 [expected.object.monadic]/23)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Value));
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{
                    _Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func), _STD move(_Value)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Ty, _Ty&>
    constexpr auto transform_error(_Fn&& _Func) & {
        static_assert(invocable<_Fn, _Err&>, "expected<T, E>::transform_error(F) requires that F is invocable with E. "
                                             "(N4950 [expected.object.monadic]/27)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Err&>>;
        static_assert(_Is_invoke_constructible<_Fn, _Err&>,
            "expected<T, E>::transform_error(F) requires that the return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.object.monadic]/27)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{in_place, _Value};
        } else {
            return expected<_Ty, _Uty>{
                _Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func), _Unexpected};
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Ty>
    constexpr auto transform_error(_Fn&& _Func) const& {
        static_assert(invocable<_Fn, const _Err&>,
            "expected<T, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.object.monadic]/27)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Err&>>;
        static_assert(_Is_invoke_constructible<_Fn, const _Err&>,
            "expected<T, E>::transform_error(F) requires that the return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.object.monadic]/27)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{in_place, _Value};
        } else {
            return expected<_Ty, _Uty>{
                _Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func), _Unexpected};
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Ty>
    constexpr auto transform_error(_Fn&& _Func) && {
        static_assert(invocable<_Fn, _Err>, "expected<T, E>::transform_error(F) requires that F is invocable with E. "
                                            "(N4950 [expected.object.monadic]/31)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Err>>;
        static_assert(_Is_invoke_constructible<_Fn, _Err>,
            "expected<T, E>::transform_error(F) requires that the return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.object.monadic]/31)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{in_place, _STD move(_Value)};
        } else {
            return expected<_Ty, _Uty>{_Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func),
                _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Ty, const _Ty>
    constexpr auto transform_error(_Fn&& _Func) const&& {
        static_assert(invocable<_Fn, const _Err>,
            "expected<T, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.object.monadic]/31)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Err>>;
        static_assert(_Is_invoke_constructible<_Fn, const _Err>,
            "expected<T, E>::transform_error(F) requires that the return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.object.monadic]/31)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{in_place, _STD move(_Value)};
        } else {
            return expected<_Ty, _Uty>{_Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func),
                _STD move(_Unexpected)};
        }
    }

    // [expected.object.eq]
    template <class _Uty, class _UErr>
        requires (!is_void_v<_Uty>)
    _NODISCARD friend constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right)
        noexcept(noexcept(_STD _Fake_copy_init<bool>(_Left._Value == *_Right))
                 && noexcept(_STD _Fake_copy_init<bool>(_Left._Unexpected == _Right.error()))) /* strengthened */ {
        if (_Left._Has_value != _Right.has_value()) {
            return false;
        } else if (_Left._Has_value) {
            return _Left._Value == *_Right;
        } else {
            return _Left._Unexpected == _Right.error();
        }
    }

    template <class _Uty>
    _NODISCARD friend constexpr bool operator==(const expected& _Left, const _Uty& _Right)
        noexcept(noexcept(static_cast<bool>(_Left._Value == _Right))) /* strengthened */ {
        if (_Left._Has_value) {
            return static_cast<bool>(_Left._Value == _Right);
        } else {
            return false;
        }
    }

    template <class _UErr>
    _NODISCARD friend constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right)
        noexcept(noexcept(static_cast<bool>(_Left._Unexpected == _Right.error()))) /* strengthened */ {
        if (_Left._Has_value) {
            return false;
        } else {
            return static_cast<bool>(_Left._Unexpected == _Right.error());
        }
    }

private:
    // These overloads force copy elision from the invoke call into _Value
    template <class _Fn, class _Ux>
    constexpr expected(_Construct_expected_from_invoke_result_tag, _Fn&& _Func, _Ux&& _Arg)
        noexcept(noexcept(static_cast<_Ty>(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
        : _Value(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg))), _Has_value{true} {}

    // For when transform is called on an expected<void, E> and requires calling _Func with no arg
    template <class _Fn>
    constexpr expected(_Construct_expected_from_invoke_result_tag, _Fn&& _Func)
        noexcept(noexcept(static_cast<_Ty>(_STD forward<_Fn>(_Func)()))) // f() is equivalent to invoke(f)
        : _Value(_STD forward<_Fn>(_Func)()), _Has_value{true} {} // f() is equivalent to invoke(f)

    template <class _Fn, class _Ux>
    constexpr expected(_Construct_expected_from_invoke_result_tag, unexpect_t, _Fn&& _Func, _Ux&& _Arg)
        noexcept(noexcept(static_cast<_Err>(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
        : _Unexpected(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg))), _Has_value{false} {}

    [[noreturn]] void _Throw_bad_expected_access_lv() const {
        _THROW(bad_expected_access{_Unexpected});
    }
    [[noreturn]] void _Throw_bad_expected_access_rv() const {
        _THROW(bad_expected_access{_STD move(_Unexpected)});
    }
    [[noreturn]] void _Throw_bad_expected_access_rv() {
        _THROW(bad_expected_access{_STD move(_Unexpected)});
    }

    union {
        _Ty _Value;
        _Err _Unexpected;
    };
    bool _Has_value;
};

template <class _Err>
concept _Expected_unary_copy_assignable = is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>;

template <class _Err>
concept _Expected_unary_move_assignable = is_move_assignable_v<_Err> && is_move_constructible_v<_Err>;

template <class _Ty, class _Err>
    requires is_void_v<_Ty>
class _NODISCARD expected<_Ty, _Err> {
private:
    static_assert(_Check_unexpected_argument<_Err>::value);

    template <class _UTy, class _UErr>
    friend class expected;

    template <class _Uty, class _UErr>
    static constexpr bool _Allow_unwrapping = !is_constructible_v<unexpected<_Err>, expected<_Uty, _UErr>&>
                                           && !is_constructible_v<unexpected<_Err>, expected<_Uty, _UErr>>
                                           && !is_constructible_v<unexpected<_Err>, const expected<_Uty, _UErr>&>
                                           && !is_constructible_v<unexpected<_Err>, const expected<_Uty, _UErr>>;

public:
    using value_type      = _Ty;
    using error_type      = _Err;
    using unexpected_type = unexpected<_Err>;

    template <class _Uty>
    using rebind = expected<_Uty, error_type>;

    // [expected.void.cons]
    constexpr expected() noexcept : _Has_value(true) {}

    constexpr expected(const expected& _Other) noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened
        requires (!is_trivially_copy_constructible_v<_Err> && is_copy_constructible_v<_Err>)
        : _Has_value(_Other._Has_value) {
        if (!_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
        }
    }

    expected(const expected&)
        requires is_trivially_copy_constructible_v<_Err>
    = default;

    expected(const expected&) = delete;

    constexpr expected(expected&& _Other) noexcept(is_nothrow_move_constructible_v<_Err>)
        requires (!is_trivially_move_constructible_v<_Err> && is_move_constructible_v<_Err>)
        : _Has_value(_Other._Has_value) {
        if (!_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
        }
    }

    expected(expected&&)
        requires is_trivially_move_constructible_v<_Err>
    = default;

    template <class _Uty, class _UErr>
        requires _Different_from<expected<_Uty, _UErr>, expected> && is_void_v<_Uty>
              && is_constructible_v<_Err, const _UErr&> && _Allow_unwrapping<_Uty, _UErr>
    constexpr explicit(!is_convertible_v<const _UErr&, _Err>) expected(const expected<_Uty, _UErr>& _Other)
        noexcept(is_nothrow_constructible_v<_Err, const _UErr&>) // strengthened
        : _Has_value(_Other._Has_value) {
        if (!_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
        }
    }

    template <class _Uty, class _UErr>
        requires _Different_from<expected<_Uty, _UErr>, expected> && is_void_v<_Uty> && is_constructible_v<_Err, _UErr>
              && _Allow_unwrapping<_Uty, _UErr>
    constexpr explicit(!is_convertible_v<_UErr, _Err>) expected(expected<_Uty, _UErr>&& _Other)
        noexcept(is_nothrow_constructible_v<_Err, _UErr>) // strengthened
        : _Has_value(_Other._Has_value) {
        if (!_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
        }
    }

    template <class _UErr>
        requires is_constructible_v<_Err, const _UErr&>
    constexpr explicit(!is_convertible_v<const _UErr&, _Err>) expected(const unexpected<_UErr>& _Other)
        noexcept(is_nothrow_constructible_v<_Err, const _UErr&>) // strengthened
        : _Unexpected(_Other._Unexpected), _Has_value(false) {}

    template <class _UErr>
        requires is_constructible_v<_Err, _UErr>
    constexpr explicit(!is_convertible_v<_UErr, _Err>) expected(unexpected<_UErr>&& _Other)
        noexcept(is_nothrow_constructible_v<_Err, _UErr>) // strengthened
        : _Unexpected(_STD move(_Other._Unexpected)), _Has_value(false) {}

    constexpr explicit expected(in_place_t) noexcept : _Has_value(true) {}

    template <class... _Args>
        requires is_constructible_v<_Err, _Args...>
    constexpr explicit expected(unexpect_t, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
        : _Unexpected(_STD forward<_Args>(_Vals)...), _Has_value(false) {}

    template <class _Uty, class... _Args>
        requires is_constructible_v<_Err, initializer_list<_Uty>&, _Args...>
    constexpr explicit expected(unexpect_t, initializer_list<_Uty> _Ilist, _Args&&... _Vals)
        noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Uty>&, _Args...>) // strengthened
        : _Unexpected(_Ilist, _STD forward<_Args>(_Vals)...), _Has_value(false) {}

    // [expected.void.dtor]
    constexpr ~expected()
#ifndef __clang__ // TRANSITION, LLVM-59854
        noexcept
#endif // ^^^ no workaround ^^^
    {
        if (!_Has_value) {
            _Unexpected.~_Err();
        }
    }

    ~expected()
        requires is_trivially_destructible_v<_Err>
    = default;

    // [expected.void.assign]
    constexpr expected& operator=(const expected& _Other)
        noexcept(is_nothrow_copy_constructible_v<_Err> && is_nothrow_copy_assignable_v<_Err>) // strengthened
        requires _Expected_unary_copy_assignable<_Err>
    {
        if (_Has_value && _Other._Has_value) {
            // nothing to do
        } else if (_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
            _Has_value = false;
        } else if (_Other._Has_value) {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value = true;
        } else {
            _Unexpected = _Other._Unexpected;
        }

        return *this;
    }

    expected& operator=(const expected&)
        requires _Expected_unary_copy_assignable<_Err> && _Trivially_copy_constructible_assignable_destructible<_Err>
    = default;

    expected& operator=(const expected&) = delete;

    constexpr expected& operator=(expected&& _Other)
        noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_move_assignable_v<_Err>)
        requires _Expected_unary_move_assignable<_Err>
    {
        if (_Has_value && _Other._Has_value) {
            // nothing to do
        } else if (_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
            _Has_value = false;
        } else if (_Other._Has_value) {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value = true;
        } else {
            _Unexpected = _STD move(_Other._Unexpected);
        }

        return *this;
    }

    expected& operator=(expected&&)
        requires _Expected_unary_move_assignable<_Err> && _Trivially_move_constructible_assignable_destructible<_Err>
    = default;

    template <class _UErr>
        requires is_constructible_v<_Err, const _UErr&> && is_assignable_v<_Err&, const _UErr&>
    constexpr expected& operator=(const unexpected<_UErr>& _Other)
        noexcept(is_nothrow_constructible_v<_Err, const _UErr&>
                 && is_nothrow_assignable_v<_Err&, const _UErr&>) /* strengthened */ {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _Other._Unexpected);
            _Has_value = false;
        } else {
            _Unexpected = _Other._Unexpected;
        }

        return *this;
    }

    template <class _UErr>
        requires is_constructible_v<_Err, _UErr> && is_assignable_v<_Err&, _UErr>
    constexpr expected& operator=(unexpected<_UErr>&& _Other)
        noexcept(is_nothrow_constructible_v<_Err, _UErr> && is_nothrow_assignable_v<_Err&, _UErr>) /* strengthened */ {
        if (_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
            _Has_value = false;
        } else {
            _Unexpected = _STD move(_Other._Unexpected);
        }

        return *this;
    }

    constexpr void emplace() noexcept {
        if (!_Has_value) {
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value = true;
        }
    }

    // [expected.void.swap]
    constexpr void swap(expected& _Other)
        noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
        requires is_swappable_v<_Err> && is_move_constructible_v<_Err>
    {
        using _STD swap;
        if (_Has_value && _Other._Has_value) {
            // nothing
        } else if (_Has_value) {
            _STD construct_at(_STD addressof(_Unexpected), _STD move(_Other._Unexpected));
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Other._Unexpected.~_Err();
            }
            _Has_value        = false;
            _Other._Has_value = true;
        } else if (_Other._Has_value) {
            _STD construct_at(_STD addressof(_Other._Unexpected), _STD move(_Unexpected));
            if constexpr (!is_trivially_destructible_v<_Err>) {
                _Unexpected.~_Err();
            }
            _Has_value        = true;
            _Other._Has_value = false;
        } else {
            swap(_Unexpected, _Other._Unexpected); // intentional ADL
        }
    }

    friend constexpr void swap(expected& _Left, expected& _Right)
        noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive
        requires is_swappable_v<_Err>
#else // ^^^ no workaround / workaround vvv
        requires is_swappable<_Err>::value
#endif // ^^^ workaround ^^^
              && is_move_constructible_v<_Err>
    {
        _Left.swap(_Right);
    }

    // [expected.void.obs]
    _NODISCARD constexpr explicit operator bool() const noexcept {
        return _Has_value;
    }
    _NODISCARD constexpr bool has_value() const noexcept {
        return _Has_value;
    }

    constexpr void operator*() const noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(_Has_value, "operator*() called on a std::expected that contains an error, not a value");
#endif
    }

    constexpr void value() const& {
        if (!_Has_value) {
            _Throw_bad_expected_access_lv();
        }
    }
    constexpr void value() && {
        // TRANSITION, DevCom-1638273 and LLVM-53224
        static_assert(is_copy_constructible_v<_Err>, "is_copy_constructible_v<E> must be true");
        static_assert(is_move_constructible_v<_Err>, "is_move_constructible_v<E> must be true");

        if (!_Has_value) {
            _Throw_bad_expected_access_rv();
        }
    }

    _NODISCARD constexpr const _Err& error() const& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _Unexpected;
    }
    _NODISCARD constexpr _Err& error() & noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _Unexpected;
    }
    _NODISCARD constexpr const _Err&& error() const&& noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _STD move(_Unexpected);
    }
    _NODISCARD constexpr _Err&& error() && noexcept {
#if _MSVC_STL_HARDENING_EXPECTED || _ITERATOR_DEBUG_LEVEL != 0
        _STL_VERIFY(!_Has_value, "error() called on a std::expected that contains a value, not an error");
#endif

        return _STD move(_Unexpected);
    }

    template <class _Uty = _Err>
    _NODISCARD constexpr _Err error_or(_Uty&& _Other) const& noexcept(
        is_nothrow_copy_constructible_v<_Err> && is_nothrow_convertible_v<_Uty, _Err>) /* strengthened */ {
        static_assert(
            is_copy_constructible_v<_Err>, "is_copy_constructible_v<E> must be true. (N4950 [expected.void.obs]/9)");
        static_assert(
            is_convertible_v<_Uty, _Err>, "is_convertible_v<G, E> must be true. (N4950 [expected.void.obs]/9)");

        if (_Has_value) {
            return _STD forward<_Uty>(_Other);
        } else {
            return _Unexpected;
        }
    }

    template <class _Uty = _Err>
    _NODISCARD constexpr _Err error_or(_Uty&& _Other) && noexcept(
        is_nothrow_move_constructible_v<_Err> && is_nothrow_convertible_v<_Uty, _Err>) /* strengthened */ {
        static_assert(
            is_move_constructible_v<_Err>, "is_move_constructible_v<E> must be true. (N4950 [expected.void.obs]/11)");
        static_assert(
            is_convertible_v<_Uty, _Err>, "is_convertible_v<G, E> must be true. (N4950 [expected.void.obs]/11)");

        if (_Has_value) {
            return _STD forward<_Uty>(_Other);
        } else {
            return _STD move(_Unexpected);
        }
    }

    // [expected.void.monadic]
    template <class _Fn>
        requires is_constructible_v<_Err, _Err&>
    constexpr auto and_then(_Fn&& _Func) & {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/3)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<void, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.void.monadic]/3)");

        if (_Has_value) {
            return _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
        } else {
            return _Uty{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Err>
    constexpr auto and_then(_Fn&& _Func) const& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/3)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<void, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.void.monadic]/3)");

        if (_Has_value) {
            return _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
        } else {
            return _Uty{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Err>
    constexpr auto and_then(_Fn&& _Func) && {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/7)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<void, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.void.monadic]/7)");

        if (_Has_value) {
            return _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
        } else {
            return _Uty{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, const _Err>
    constexpr auto and_then(_Fn&& _Func) const&& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::and_then(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/7)");
        static_assert(is_same_v<typename _Uty::error_type, _Err>,
            "expected<void, E>::and_then(F) requires the error type of the return type of F to be E. "
            "(N4950 [expected.void.monadic]/7)");

        if (_Has_value) {
            return _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
        } else {
            return _Uty{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
    constexpr auto or_else(_Fn&& _Func) & {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Err&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/10)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<void, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.void.monadic]/10)");

        if (_Has_value) {
            return _Uty{};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _Unexpected);
        }
    }

    template <class _Fn>
    constexpr auto or_else(_Fn&& _Func) const& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Err&>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/10)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<void, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.void.monadic]/10)");

        if (_Has_value) {
            return _Uty{};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _Unexpected);
        }
    }

    template <class _Fn>
    constexpr auto or_else(_Fn&& _Func) && {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, _Err>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/13)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<void, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.void.monadic]/13)");

        if (_Has_value) {
            return _Uty{};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Unexpected));
        }
    }

    template <class _Fn>
    constexpr auto or_else(_Fn&& _Func) const&& {
        using _Uty = remove_cvref_t<invoke_result_t<_Fn, const _Err>>;

        static_assert(_Is_specialization_v<_Uty, expected>,
            "expected<void, E>::or_else(F) requires the return type of F to be a specialization of expected. "
            "(N4950 [expected.void.monadic]/13)");
        static_assert(is_same_v<typename _Uty::value_type, _Ty>,
            "expected<void, E>::or_else(F) requires the value type of the return type of F to be T. "
            "(N4950 [expected.void.monadic]/13)");

        if (_Has_value) {
            return _Uty{};
        } else {
            return _STD invoke(_STD forward<_Fn>(_Func), _STD move(_Unexpected));
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, _Err&>
    constexpr auto transform(_Fn&& _Func) & {
        static_assert(invocable<_Fn>, "expected<void, E>::transform(F) requires that F is invocable with no arguments. "
                                      "(N4950 [expected.void.monadic]/17)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn>, "expected<void, E>::transform(F) requires that the return "
                                                         "type of F is constructible with the result of "
                                                         "invoking f. (N4950 [expected.void.monadic]/17)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{_Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_copy_constructible_v<_Err>
    constexpr auto transform(_Fn&& _Func) const& {
        static_assert(invocable<_Fn>, "expected<void, E>::transform(F) requires that F is invocable with no arguments. "
                                      "(N4950 [expected.void.monadic]/17)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn>, "expected<void, E>::transform(F) requires that the return "
                                                         "type of F is constructible with the result of "
                                                         "invoking f. (N4950 [expected.void.monadic]/17)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{_Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _Unexpected};
        }
    }

    template <class _Fn>
        requires is_move_constructible_v<_Err>
    constexpr auto transform(_Fn&& _Func) && {
        static_assert(invocable<_Fn>, "expected<void, E>::transform(F) requires that F is invocable with no arguments. "
                                      "(N4950 [expected.void.monadic]/21)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn>, "expected<void, E>::transform(F) requires that the return "
                                                         "type of F is constructible with the result of "
                                                         "invoking f. (N4950 [expected.void.monadic]/21)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{_Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
        requires is_constructible_v<_Err, const _Err>
    constexpr auto transform(_Fn&& _Func) const&& {
        static_assert(invocable<_Fn>, "expected<void, E>::transform(F) requires that F is invocable with no arguments. "
                                      "(N4950 [expected.void.monadic]/21)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn>>;

        if constexpr (!is_void_v<_Uty>) {
            static_assert(_Is_invoke_constructible<_Fn>, "expected<void, E>::transform(F) requires that the return "
                                                         "type of F is constructible with the result of "
                                                         "invoking f. (N4950 [expected.void.monadic]/21)");
        }
        static_assert(_Check_expected_argument<_Uty>::value);

        if (_Has_value) {
            if constexpr (is_void_v<_Uty>) {
                _STD forward<_Fn>(_Func)(); // f() is equivalent to invoke(f)
                return expected<_Uty, _Err>{};
            } else {
                return expected<_Uty, _Err>{_Construct_expected_from_invoke_result_tag{}, _STD forward<_Fn>(_Func)};
            }
        } else {
            return expected<_Uty, _Err>{unexpect, _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
    constexpr auto transform_error(_Fn&& _Func) & {
        static_assert(invocable<_Fn, _Err&>,
            "expected<void, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.void.monadic]/24)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Err&>>;
        static_assert(_Is_invoke_constructible<_Fn, _Err&>, "expected<void, E>::transform_error(F) requires that the "
                                                            "return type of F is constructible with the result of "
                                                            "invoking f. (N4950 [expected.void.monadic]/24)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{};
        } else {
            return expected<_Ty, _Uty>{
                _Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func), _Unexpected};
        }
    }

    template <class _Fn>
    constexpr auto transform_error(_Fn&& _Func) const& {
        static_assert(invocable<_Fn, const _Err&>,
            "expected<void, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.void.monadic]/24)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Err&>>;
        static_assert(_Is_invoke_constructible<_Fn, const _Err&>,
            "expected<void, E>::transform_error(F) requires that the "
            "return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.void.monadic]/24)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{};
        } else {
            return expected<_Ty, _Uty>{
                _Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func), _Unexpected};
        }
    }

    template <class _Fn>
    constexpr auto transform_error(_Fn&& _Func) && {
        static_assert(invocable<_Fn, _Err>,
            "expected<void, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.void.monadic]/27)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, _Err>>;
        static_assert(_Is_invoke_constructible<_Fn, _Err>, "expected<void, E>::transform_error(F) requires that the "
                                                           "return type of F is constructible with the result of "
                                                           "invoking f. (N4950 [expected.void.monadic]/27)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{};
        } else {
            return expected<_Ty, _Uty>{_Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func),
                _STD move(_Unexpected)};
        }
    }

    template <class _Fn>
    constexpr auto transform_error(_Fn&& _Func) const&& {
        static_assert(invocable<_Fn, const _Err>,
            "expected<void, E>::transform_error(F) requires that F is invocable with E. "
            "(N4950 [expected.void.monadic]/27)");
        using _Uty = remove_cv_t<invoke_result_t<_Fn, const _Err>>;
        static_assert(_Is_invoke_constructible<_Fn, const _Err>,
            "expected<void, E>::transform_error(F) requires that the "
            "return type of F is constructible with the result of "
            "invoking f. (N4950 [expected.void.monadic]/27)");

        static_assert(_Check_unexpected_argument<_Uty>::value);

        if (_Has_value) {
            return expected<_Ty, _Uty>{};
        } else {
            return expected<_Ty, _Uty>{_Construct_expected_from_invoke_result_tag{}, unexpect, _STD forward<_Fn>(_Func),
                _STD move(_Unexpected)};
        }
    }

    // [expected.void.eq]
    template <class _Uty, class _UErr>
        requires is_void_v<_Uty>
    _NODISCARD friend constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right)
        noexcept(noexcept(static_cast<bool>(_Left._Unexpected == _Right.error()))) /* strengthened */ {
        if (_Left._Has_value != _Right.has_value()) {
            return false;
        } else {
            return _Left._Has_value || static_cast<bool>(_Left._Unexpected == _Right.error());
        }
    }

    template <class _UErr>
    _NODISCARD friend constexpr bool operator==(const expected& _Left, const unexpected<_UErr>& _Right)
        noexcept(noexcept(static_cast<bool>(_Left._Unexpected == _Right.error()))) /* strengthened */ {
        if (_Left._Has_value) {
            return false;
        } else {
            return static_cast<bool>(_Left._Unexpected == _Right.error());
        }
    }

private:
    template <class _Fn, class _Ux>
    constexpr expected(_Construct_expected_from_invoke_result_tag, unexpect_t, _Fn&& _Func, _Ux&& _Arg)
        noexcept(noexcept(_Err(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
        : _Unexpected(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg))), _Has_value{false} {}

    [[noreturn]] void _Throw_bad_expected_access_lv() const {
        _THROW(bad_expected_access{_Unexpected});
    }
    [[noreturn]] void _Throw_bad_expected_access_rv() {
        _THROW(bad_expected_access{_STD move(_Unexpected)});
    }

    union {
        _Err _Unexpected;
    };
    bool _Has_value;
};

_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)
#endif // ^^^ _HAS_CXX23 ^^^
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _EXPECTED_
